astx-redux-util
Version:
Several redux reducer composition utilities.
89 lines (72 loc) • 3.63 kB
JavaScript
;
exports.__esModule = true;
exports.default = joinReducers;
var _lodash = require('lodash.isfunction');
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = require('lodash.last');
var _lodash4 = _interopRequireDefault(_lodash3);
var _verify = require('../util/verify');
var _verify2 = _interopRequireDefault(_verify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Create a higher-order reducer by combining two or more reducers,
* logically executing each in sequence (in essence combining their
* functionality into one). This is useful when combining various
* reducer types into one logical construct.
*
* **Please Note:** Because each reducer is able to build on what has
* been accomplished by a prior reducer, joinReducers cumulatively
* passes the state parameter that was returned from any prior reducer
* (in the chain of reducers to execute). In essence this is an
* accumulative process. While this does NOT relax the immutable
* constraint of the reducer's state parameter, it is possible for a
* down-stream reducer to receive a state parameter that is a
* different instance from the start of the reduction process (because
* an up-stream reducer needed to alter it in some way).
*
* The {{book.guide.devGuide}} discusses joinReducers() in more detail
* (see {{book.guide.conceptJoin}}), and additional examples can
* be found in {{book.guide.fullExample}}.
*
* @param {...reducerFn} reducerFns two or more reducer functions to join
* together.
*
* @param {InitialState} [initialState] - the optional fall-back state
* value used during the state initialization boot-strap process.
*
* @returns {reducerFn} a newly created reducer function (described above).
*/
function joinReducers() {
for (var _len = arguments.length, reducerFns = Array(_len), _key = 0; _key < _len; _key++) {
reducerFns[_key] = arguments[_key];
}
// define our initialState parameter (optionally, the last parameter)
// NOTE: We have to do this programatically because our function
// accepts variable number of arguments.
var initialState = (0, _lodash2.default)((0, _lodash4.default)(reducerFns)) ? undefined : reducerFns.pop();
// validate params
var check = _verify2.default.prefix('AstxReduxUtil.joinReducers() parameter violation: ');
check(reducerFns && reducerFns.length >= 2, 'two or more reducerFn arguments are required');
// ... each arg MUST be a function (reducerFn)
var badArgNum = reducerFns.reduce(function (firstBadArgNum, reducerFn, indx) {
return firstBadArgNum || ((0, _lodash2.default)(reducerFn) ? 0 : indx + 1);
}, 0);
check(!badArgNum, 'argument position number ' + badArgNum + ' is NOT a function ... expecting two or more reducerFns to join together');
// expose our new higher-order reducer
return function () {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];
var originalReducerState = arguments[2];
// maintain the originalReducerState as the immutable state
// at the time of the start of the reduction process
// ... in support of joinReducers()
// ... for more info, refer to the Dev Guide {{book.guide.originalReducerState}}
if (originalReducerState === undefined) {
originalReducerState = state;
}
// execute each reducerFn in sequence
return reducerFns.reduce(function (nextState, reducerFn) {
return reducerFn(nextState, action, originalReducerState);
}, state);
};
}