astx-redux-util
Version:
Several redux reducer composition utilities.
109 lines (91 loc) • 4.3 kB
JavaScript
;
exports.__esModule = true;
exports.default = conditionalReducer;
var _lodash = require('lodash.identity');
var _lodash2 = _interopRequireDefault(_lodash);
var _lodash3 = require('lodash.isfunction');
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 that conditionally executes one of
* the supplied reducerFns, based on the conditionalFn() return
* directive.
*
* The {{book.guide.devGuide}} discusses conditionalReducer() in more detail
* (see {{book.guide.conceptConditional}}), and additional examples can
* be found in {{book.guide.conceptJoin}} and {{book.guide.fullExample}}.
*
* @param {conditionalReducerCB} conditionalFn - a callback function
* whose return value determines which reducerFn is executed
* ... truthy: thenReducerFn(), falsy: elseReducerFn().
*
* @param {reducerFn} thenReducerFn - the "wrapped" reducer invoked
* when conditionalFn returns truthy.
*
* @param {reducerFn} [elseReducerFn=identity] - the
* optional "wrapped" reducer invoked when conditionalFn returns
* falsy. DEFAULT: [identity function](https://lodash.com/docs#identity)
*
* @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 conditionalReducer(conditionalFn, thenReducerFn) {
var elseReducerFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _lodash2.default;
var initialState = arguments[3];
// validate params
var check = _verify2.default.prefix('AstxReduxUtil.conditionalReducer() parameter violation: ');
check(conditionalFn, 'conditionalFn argument is required');
check((0, _lodash4.default)(conditionalFn), 'conditionalFn argument is NOT a function');
check(thenReducerFn, 'thenReducerFn argument is required');
check((0, _lodash4.default)(thenReducerFn), 'thenReducerFn argument is NOT a function');
check((0, _lodash4.default)(elseReducerFn), 'elseReducerFn argument is NOT a function');
// expose our new higher-order reducer
// NOTE: For more info on he originalReducerState parameter, refer to the Dev Guide {{book.guide.originalReducerState}}
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 either thenReducerFn or elseReducerFn, based on conditionalFn
return conditionalFn(state, action, originalReducerState) ? thenReducerFn(state, action, originalReducerState) : elseReducerFn(state, action, originalReducerState);
};
}
//***
//*** Specification: conditionalReducerCB
//***
/**
* A callback function (used in {{book.api.conditionalReducer}}) whose
* return value determines which reducerFn is executed.
*
* @callback conditionalReducerCB
*
* @param {*} state - The current immutable state that is the
* reduction target.
*
* @param {Action} action - The standard redux Action object that
* drives the reduction process.
*
* @param {*} originalReducerState - The immutable state at the time
* of the start of the reduction process.
*
* This is useful in determining whether state has changed within a
* series of reductions {{book.api.joinReducers}} ... because each
* individual reducer only has visibility of the state within it's own
* reduction process.
*
* Further information can be found in the
* {{book.guide.originalReducerState}} discussion of the {{book.guide.devGuide}}.
*
* @returns {truthy} A truthy value indicating which reducerFn is
* executed ... truthy: thenReducerFn(), falsy: elseReducerFn().
*/