UNPKG

@dr.pogodin/react-global-state

Version:
97 lines (94 loc) 3.74 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.getGlobalState = getGlobalState; exports.getSsrContext = getSsrContext; var _lodash = require("lodash"); var _react = require("react"); var _GlobalState = _interopRequireDefault(require("./GlobalState")); var _jsxRuntime = require("react/jsx-runtime"); const Context = /*#__PURE__*/(0, _react.createContext)(null); /** * Gets {@link GlobalState} instance from the context. In most cases * you should use {@link useGlobalState}, and other hooks to interact with * the global state, instead of accessing it directly. * @return */ function getGlobalState() { // TODO: Think about it: on one hand we on purpose called this function // as getGlobalState(), so that ppl looking for the state hook prefer using // useGlobalState(), while this getGlobalState() is reserved for nieche cases; // on the other hand, perhaps we can rename it into useSomething, to both // follow conventions, and to keep stuff clearly named at the same time. // eslint-disable-next-line react-hooks/rules-of-hooks const globalState = (0, _react.use)(Context); if (!globalState) throw new Error('Missing GlobalStateProvider'); return globalState; } /** * @category Hooks * @desc Gets SSR context. * @param throwWithoutSsrContext If `true` (default), * this hook will throw if no SSR context is attached to the global state; * set `false` to not throw in such case. In either case the hook will throw * if the {@link <GlobalStateProvider>} (hence the state) is missing. * @returns SSR context. * @throws * - If current component has no parent {@link <GlobalStateProvider>} * in the rendered React tree. * - If `throwWithoutSsrContext` is `true`, and there is no SSR context attached * to the global state provided by {@link <GlobalStateProvider>}. */ function getSsrContext(throwWithoutSsrContext = true) { const { ssrContext } = getGlobalState(); if (!ssrContext && throwWithoutSsrContext) { throw new Error('No SSR context found'); } return ssrContext; } /** * Provides global state to its children. * @param prop.children Component children, which will be provided with * the global state, and rendered in place of the provider. * @param prop.initialState Initial content of the global state. * @param prop.ssrContext Server-side rendering (SSR) context. * @param prop.stateProxy This option is useful for code * splitting and SSR implementation: * - If `true`, this provider instance will fetch and reuse the global state * from a parent provider. * - If `GlobalState` instance, it will be used by this provider. * - If not given, a new `GlobalState` instance will be created and used. */ const GlobalStateProvider = ({ children, ...rest }) => { const localStateRef = (0, _react.useRef)(undefined); let state; // TODO: Revise. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if ('stateProxy' in rest && rest.stateProxy) { localStateRef.current = undefined; state = rest.stateProxy === true ? getGlobalState() : rest.stateProxy; } else { if (!localStateRef.current) { const { initialState, ssrContext } = rest; localStateRef.current = new _GlobalState.default((0, _lodash.isFunction)(initialState) ? initialState() : initialState, ssrContext); } state = localStateRef.current; } return /*#__PURE__*/(0, _jsxRuntime.jsx)(Context, { value: state, children: children }); }; var _default = exports.default = GlobalStateProvider; //# sourceMappingURL=GlobalStateProvider.js.map