reshow-flux
Version:
The smallest react flux and Fast hook alternative
99 lines (94 loc) • 2.83 kB
JavaScript
;
var _interopRequireDefault = require("reshow-runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _objectSpread2 = _interopRequireDefault(require("reshow-runtime/helpers/objectSpread2"));
var _react = require("react");
// @ts-check
/**
* @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 = (0, _react.useRef)();
lastProps.current = {
store: store,
heeding: heeding
};
/**
* @type any
*/
var lastEmit = (0, _react.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 _lastProps$current = lastProps.current,
store = _lastProps$current.store,
heeding = _lastProps$current.heeding;
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 = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, lastEmit.current), {}, {
storeState: storeState,
action: action,
prevStoreState: prevStoreState,
notify: notify
});
return myHeeding(lastEmit);
};
store.addListener(myListener);
return function () {
return store.removeListener(myListener);
};
};
var getState = function getState() {
return lastEmit.current.state;
};
return (0, _react.useSyncExternalStore)(subscribe, getState, getState);
};
var _default = exports["default"] = useStore;
module.exports = exports.default;