reshow-flux
Version:
The smallest react flux and Fast hook alternative
95 lines (90 loc) • 2.42 kB
JavaScript
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;