UNPKG

@tommostools/use-context-selector

Version:

Hook for simple context slicing in React

57 lines (55 loc) 2.32 kB
"use strict"; (() => { var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // src/index.ts var import_contexto = __require("contexto"); var import_react = __require("react"); function useContextSelector(context, rawSelector, deps) { const subscribe = (0, import_contexto.useSubscriber)(); const selector = (0, import_react.useCallback)( rawSelector instanceof Function ? rawSelector : (value) => value[rawSelector], // Ignore changes to rawSelector if it's a function – caller has responsibility for supplying the dependencies rawSelector instanceof Function ? deps || [] : [rawSelector] ); const subscribeWrapper = (0, import_react.useCallback)( () => { const [value, unsubscribe] = subscribe( context, (newValue) => setState((state2) => { const selection = selector(newValue); return selection !== state2.selection ? { value: newValue, selection, selector, context, unsubscribe } : state2; }) ); return { value, unsubscribe }; }, [context, selector, subscribe] ); const [state, setState] = (0, import_react.useState)(() => { const { value, unsubscribe } = subscribeWrapper(); return { value, selection: selector(value), selector, context, unsubscribe }; }); (0, import_react.useEffect)( () => { if (context !== state.context || selector !== state.selector) { let { value, unsubscribe, selection } = state; if (context !== state.context) { state.unsubscribe(); ({ value, unsubscribe } = subscribeWrapper()); } if (selector !== state.selector || value !== state.value) selection = selector(value); setState({ value, selection, selector, context, unsubscribe }); } }, [state, context, selector, subscribeWrapper] ); return state.selection; } var src_default = useContextSelector; })();