@nanostores/react
Version:
React integration for Nano Stores, a tiny state manager with many atomic tree-shakable stores
31 lines (23 loc) • 836 B
JavaScript
import { listenKeys } from 'nanostores'
import { useCallback, useRef, useSyncExternalStore } from 'react'
let emit = (snapshotRef, onChange) => value => {
if (snapshotRef.current === value) return
snapshotRef.current = value
onChange()
}
export function useStore(store, { keys, deps = [store, keys], ssr } = {}) {
let snapshotRef = useRef()
snapshotRef.current = store.get()
let subscribe = useCallback(onChange => {
emit(snapshotRef, onChange)(store.value)
return keys?.length > 0
? listenKeys(store, keys, emit(snapshotRef, onChange))
: store.listen(emit(snapshotRef, onChange))
}, deps)
let get = () => snapshotRef.current
let server = get
if (ssr && 'init' in store) {
server = ssr === 'initial' ? () => store.init : ssr
}
return useSyncExternalStore(subscribe, get, server)
}