react-sweet-state
Version:
Global + local state combining the best of Redux and Context API
76 lines (62 loc) • 2.5 kB
JavaScript
;
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];
};
}