UNPKG

reshow-flux

Version:
144 lines (136 loc) 4.26 kB
"use strict"; var _interopRequireDefault = require("reshow-runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = void 0; var _react = require("react"); var _reshowHooks = require("reshow-hooks"); var _reshowConstant = require("reshow-constant"); var _getStore = _interopRequireDefault(require("./getStore.js")); // @ts-check var handleShouldComponentUpdate = function handleShouldComponentUpdate(_ref) { var calOptions = _ref.calOptions, shouldComponentUpdate = _ref.shouldComponentUpdate, calculateState = _ref.calculateState, prev = _ref.prev, props = _ref.props; var nextState = calculateState(prev.state, calOptions); var bUpdate = shouldComponentUpdate ? shouldComponentUpdate({ prev: prev, nextProps: props, nextState: nextState }) : nextState !== prev.state; if (bUpdate) { return { props: props, state: nextState, __init__: _reshowConstant.T_TRUE }; } else { prev.__init__ = _reshowConstant.T_TRUE; return prev; } }; /** * @template StateType * @template ActionType * @typedef {import("reshow-flux-base").StoreObject<StateType, ActionType>} StoreObject */ /** * @template StateType * @template ActionType * @typedef {object} UseConnectWithStore * @property {StoreObject<StateType, ActionType>} store */ /** * @template StateType * * @callback CalculateStateCallback * @param {StateType|any} prevState * @param {any} calculateOptions * @returns {StateType} */ /** * @template StateType * * @callback GetStateCallback * @param {any} props * @returns {StateType} */ /** * @template StateType * @template ActionType * * @typedef {object} UseConnectOption * @property {CalculateStateCallback<StateType>} calculateState * @property {boolean} [shouldComponentUpdate] * @property {function(any):StoreObject<StateType, ActionType>} [storeLocator] * @property {string} [displayName] */ var useConnect = /** * @template StateType * @template ActionType * * @param {UseConnectOption<StateType, ActionType>} inputOptions * @returns {GetStateCallback<StateType>} */ function useConnect(inputOptions) { return function (props) { /** * @type UseConnectWithStore<StateType, ActionType> & UseConnectOption<StateType, ActionType> */ var options = (0, _getStore["default"])({ options: inputOptions, props: props }); var calculateState = options.calculateState, shouldComponentUpdate = options.shouldComponentUpdate, _options$displayName = options.displayName, displayName = _options$displayName === void 0 ? "useConnect" : _options$displayName; var calOptions = /**@type any*/options; (0, _react.useDebugValue)(displayName); var _useState = (0, _react.useState)(function () { return { props: props, state: calculateState({}, calOptions), __init__: _reshowConstant.T_FALSE }; }), data = _useState[0], setData = _useState[1]; var isMount = (0, _reshowHooks.useMounted)(); (0, _react.useEffect)(function () { var handleChange = function handleChange(/** @type any */storeSyncState) { if (_reshowConstant.T_TRUE === isMount()) { /** * Why storeSyncState? * * It's useful for synchronous programing to get correct data, * when it pass from reducer directly. */ calOptions.storeSyncState = storeSyncState; setData(function (prev) { return handleShouldComponentUpdate({ calOptions: calOptions, calculateState: calculateState, shouldComponentUpdate: shouldComponentUpdate, prev: prev, props: props }); }); } return storeSyncState; }; if (!data.__init__ || data.props !== props) { handleChange(options.store.getState()); } options.store.addListener(handleChange); return function () { options.store.removeListener(handleChange); }; }, props.renewProps ? [props] : []); return /**@type StateType*/data.state || {}; }; }; var _default = exports["default"] = useConnect; module.exports = exports.default;