UNPKG

use-s-react

Version:

useS is a minimal yet powerful React hook for managing both local and global state — with zero boilerplate

50 lines (49 loc) 1.76 kB
import { useMemo, useState, useCallback, useSyncExternalStore } from "react"; import { FullCopy } from "full-copy"; import { deepAssign, hasChanged, normalizeUseSArgs } from "../functions"; import { createState, setGlobalState, isKeyInitialized, getGlobalSnapshot, subscribeToGlobalState, } from "../store"; export function useS(config) { const { initialValue, key } = normalizeUseSArgs(config); if (key && typeof key === "string" && key.length > 0 && !isKeyInitialized(key)) { createState(key, initialValue); } const [subscribe, getSnapshot] = useMemo(() => { if (!key) { return [() => () => { }, () => initialValue]; } return [ (cb) => subscribeToGlobalState(key, cb), () => getGlobalSnapshot(key), ]; }, [key, initialValue]); const globalState = useSyncExternalStore(subscribe, getSnapshot); const [localState, setLocalState] = useState(initialValue); const setState = useCallback((val) => { const current = key ? getGlobalSnapshot(key) : localState; const resolved = typeof val === "function" ? val(current) : val; const { changed, type } = hasChanged(current, resolved); if (!changed) return; let newState; if (type === "object") { const cloned = FullCopy(current); deepAssign(cloned, resolved); newState = cloned; } else { newState = resolved; } if (key) { setGlobalState(key, newState); } else { setLocalState(newState); } }, [key, localState]); return [key ? globalState : localState, setState]; }