File size: 1,237 Bytes
abcf568 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import { useEffect, useRef, useState } from 'react'
import type { StudioCommandPanelStore } from './store'
export function useCommandStoreSelector<T>(
store: StudioCommandPanelStore,
selector: (snapshot: ReturnType<StudioCommandPanelStore['getSnapshot']>) => T,
isEqual: (left: T, right: T) => boolean = Object.is,
) {
const selectorRef = useRef(selector)
const isEqualRef = useRef(isEqual)
selectorRef.current = selector
isEqualRef.current = isEqual
const [selected, setSelected] = useState(() => selector(store.getSnapshot()))
const selectedRef = useRef(selected)
useEffect(() => {
selectedRef.current = selected
}, [selected])
useEffect(() => {
const unsubscribe = store.subscribe(() => {
const nextSelected = selectorRef.current(store.getSnapshot())
if (isEqualRef.current(selectedRef.current, nextSelected)) {
return
}
selectedRef.current = nextSelected
setSelected(nextSelected)
})
const nextSelected = selectorRef.current(store.getSnapshot())
if (!isEqualRef.current(selectedRef.current, nextSelected)) {
selectedRef.current = nextSelected
setSelected(nextSelected)
}
return unsubscribe
}, [store])
return selected
}
|