95 lines
3.5 KiB
JavaScript
95 lines
3.5 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
exports.pureFinalPropsSelectorFactory = pureFinalPropsSelectorFactory;
|
||
|
exports.default = finalPropsSelectorFactory;
|
||
|
|
||
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
||
|
|
||
|
var _verifySubselectors = _interopRequireDefault(require("./verifySubselectors"));
|
||
|
|
||
|
const _excluded = ["initMapStateToProps", "initMapDispatchToProps", "initMergeProps"];
|
||
|
|
||
|
function pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, {
|
||
|
areStatesEqual,
|
||
|
areOwnPropsEqual,
|
||
|
areStatePropsEqual
|
||
|
}) {
|
||
|
let hasRunAtLeastOnce = false;
|
||
|
let state;
|
||
|
let ownProps;
|
||
|
let stateProps;
|
||
|
let dispatchProps;
|
||
|
let mergedProps;
|
||
|
|
||
|
function handleFirstCall(firstState, firstOwnProps) {
|
||
|
state = firstState;
|
||
|
ownProps = firstOwnProps;
|
||
|
stateProps = mapStateToProps(state, ownProps);
|
||
|
dispatchProps = mapDispatchToProps(dispatch, ownProps);
|
||
|
mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
|
||
|
hasRunAtLeastOnce = true;
|
||
|
return mergedProps;
|
||
|
}
|
||
|
|
||
|
function handleNewPropsAndNewState() {
|
||
|
stateProps = mapStateToProps(state, ownProps);
|
||
|
if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps);
|
||
|
mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
|
||
|
return mergedProps;
|
||
|
}
|
||
|
|
||
|
function handleNewProps() {
|
||
|
if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state, ownProps);
|
||
|
if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps);
|
||
|
mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
|
||
|
return mergedProps;
|
||
|
}
|
||
|
|
||
|
function handleNewState() {
|
||
|
const nextStateProps = mapStateToProps(state, ownProps);
|
||
|
const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps);
|
||
|
stateProps = nextStateProps;
|
||
|
if (statePropsChanged) mergedProps = mergeProps(stateProps, dispatchProps, ownProps);
|
||
|
return mergedProps;
|
||
|
}
|
||
|
|
||
|
function handleSubsequentCalls(nextState, nextOwnProps) {
|
||
|
const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps);
|
||
|
const stateChanged = !areStatesEqual(nextState, state, nextOwnProps, ownProps);
|
||
|
state = nextState;
|
||
|
ownProps = nextOwnProps;
|
||
|
if (propsChanged && stateChanged) return handleNewPropsAndNewState();
|
||
|
if (propsChanged) return handleNewProps();
|
||
|
if (stateChanged) return handleNewState();
|
||
|
return mergedProps;
|
||
|
}
|
||
|
|
||
|
return function pureFinalPropsSelector(nextState, nextOwnProps) {
|
||
|
return hasRunAtLeastOnce ? handleSubsequentCalls(nextState, nextOwnProps) : handleFirstCall(nextState, nextOwnProps);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// TODO: Add more comments
|
||
|
// The selector returned by selectorFactory will memoize its results,
|
||
|
// allowing connect's shouldComponentUpdate to return false if final
|
||
|
// props have not changed.
|
||
|
function finalPropsSelectorFactory(dispatch, _ref) {
|
||
|
let {
|
||
|
initMapStateToProps,
|
||
|
initMapDispatchToProps,
|
||
|
initMergeProps
|
||
|
} = _ref,
|
||
|
options = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
|
||
|
const mapStateToProps = initMapStateToProps(dispatch, options);
|
||
|
const mapDispatchToProps = initMapDispatchToProps(dispatch, options);
|
||
|
const mergeProps = initMergeProps(dispatch, options);
|
||
|
|
||
|
if (process.env.NODE_ENV !== 'production') {
|
||
|
(0, _verifySubselectors.default)(mapStateToProps, mapDispatchToProps, mergeProps);
|
||
|
}
|
||
|
|
||
|
return pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, options);
|
||
|
}
|