reshow-flux
Version:
The smallest react flux and Fast hook alternative
144 lines (136 loc) • 4.26 kB
JavaScript
"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;