UNPKG

reshow-flux

Version:
95 lines (90 loc) 2.42 kB
import _objectSpread from "reshow-runtime/es/helpers/objectSpread2"; // @ts-check import { useSyncExternalStore, useRef } from "react"; /** * @typedef {object} Emitter */ /** * @template StateType * @template ActionType * @typedef {import("reshow-flux-base/types/createReducer").FluxHandler<StateType, ActionType>} FluxHandler */ /** * @template StateType * @template ActionType * @typedef {import("reshow-flux-base").StoreObject<StateType, ActionType>} StoreObject */ /** * How to use? * * import { useEffect } from "react"; * import { useStore, ImmutableStore } from "reshow-flux"; * const [store, dispatch] = ImmutableStore(); * const Comp = props => { * const state = useStore(store); * useEffect(()=>dispatch({foo: "bar"}), []); * return <div>{state.get("foo")}</div>; * } * * @template StateType * @template ActionType * @param {StoreObject<StateType, ActionType>} store * @param {function(Emitter):any} [heeding] * @returns {StateType} */ var useStore = function useStore(store, heeding) { /** * @type any */ var lastProps = useRef(); lastProps.current = { store, heeding }; /** * @type any */ var lastEmit = useRef(); if (!lastEmit.current) { lastEmit.current = { /** * Pass empty {} to heeding, that easy use * if(!emit.current){return initState;} * inside heeding. */ state: heeding ? heeding({}) : store.getState() }; } var subscribe = function subscribe(/** @type function*/notify) { var { store, heeding } = lastProps.current; var myHeeding = heeding || function (/** @type Emitter*/emit) { emit.current.state = emit.current.storeState; emit.current.notify(); return emit.current.state; }; /** * @type FluxHandler<StateType, ActionType> */ var myListener = function myListener(storeState, action, prevStoreState) { lastEmit.current = _objectSpread(_objectSpread({}, lastEmit.current), {}, { storeState, action, prevStoreState, notify }); return myHeeding(lastEmit); }; store.addListener(myListener); return function () { return store.removeListener(myListener); }; }; var getState = function getState() { return lastEmit.current.state; }; return useSyncExternalStore(subscribe, getState, getState); }; export default useStore;