redux-conditional
Version:
Make sharing reducers easy by conditionally applying actions to shared Redux reducers.
50 lines (37 loc) • 1.42 kB
JavaScript
import {
conditionalDefaultSubKey,
simpleConditional,
} from './simpleConditional';
const unknownAction = { type: Symbol('REDUX CONDITIONAL UNKNOWN TYPE') };
const conditionalReducer = (conditionFn, reducer) => (state, action) => (
reducer(state, conditionFn(state, action) ? action : unknownAction)
);
const normalizeTargets = (targets, conditionFnMaker) => {
if (Array.isArray(targets)) {
return targets.map(key => ({ key, conditionFn: conditionFnMaker(key) }));
}
return Object.keys(targets).map(key => ({ key, conditionFn: conditionFnMaker(targets[key]) }));
};
// simpleConditional().default expects the "data" can be accessed by action[conditionalKey][conditionalDefaultSubKey]
const conditionalReducerByKey = (targets, { conditionMaker } = simpleConditional().default) => {
const normalized = normalizeTargets(targets, conditionMaker);
return reducer => (state, action) => {
const nextState = {};
let changed = false;
normalized.forEach((target) => {
let subState = state;
if (state) {
subState = state[target.key];
}
nextState[target.key] = conditionalReducer(target.conditionFn, reducer)(subState, action);
changed = changed || nextState[target.key] !== subState;
});
return changed ? nextState : state;
};
};
export {
conditionalReducer,
conditionalReducerByKey,
conditionalDefaultSubKey,
simpleConditional,
};