UNPKG

react-sweet-state

Version:

Global + local state combining the best of Redux and Context API

76 lines (62 loc) 2.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createActionsHook = createActionsHook; exports.createHook = createHook; exports.createStateHook = createStateHook; var _react = require("react"); var _shim = require("use-sync-external-store/shim"); var _context = require("../context"); var _createSelector = require("../utils/create-selector"); var EMPTY_SELECTOR = function EMPTY_SELECTOR() { return undefined; }; var DEFAULT_SELECTOR = function DEFAULT_SELECTOR(state) { return state; }; function createHook(Store) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, selector = _ref.selector; return function useSweetState(propsArg) { var _useContext = (0, _react.useContext)(_context.Context), retrieveStore = _useContext.retrieveStore; var _retrieveStore = retrieveStore(Store), storeState = _retrieveStore.storeState, actions = _retrieveStore.actions; var hasPropsArg = propsArg !== undefined; var propsArgRef = (0, _react.useRef)(propsArg); propsArgRef.current = propsArg; var stateSelector = (0, _react.useMemo)(function () { return selector ? (0, _createSelector.getSelectorInstance)(selector, storeState, hasPropsArg) : selector === null ? EMPTY_SELECTOR : DEFAULT_SELECTOR; }, [hasPropsArg, storeState]); var forceUpdate = (0, _react.useState)({})[1]; var getSnapshot = (0, _react.useCallback)(function () { // parent scope has changed and notify was explicitly triggered by the container // we need to force the hook to re-render to listen new storeState if (retrieveStore(Store).storeState !== storeState) forceUpdate({}); var state = storeState.getState(); return stateSelector(state, propsArgRef.current); }, [retrieveStore, storeState, stateSelector, forceUpdate]); var currentState = (0, _shim.useSyncExternalStore)(storeState.subscribe, getSnapshot, getSnapshot); return [currentState, actions]; }; } function createActionsHook(Store) { var useHook = createHook(Store, { selector: null }); return function useSweetStateActions() { return useHook()[1]; }; } function createStateHook(Store) { var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, selector = _ref2.selector; var useHook = createHook(Store, { selector: selector }); return function useSweetStateState(propsArg) { return useHook(propsArg)[0]; }; }