Turns multiple reducer functions, into a single reducer function, with the support of declaring the initial states as default parameters.
It will call all the child reducers, and gather their results into a single state object by assign
the result objects together from left to right.
The reason for the name is it flatten the state
of using the combineReducers
in redux.
npm install --save flat-combine-reducers
To prevent the reducer growing too large, Redux provides a function called combineReducers
to let us structure the reducer. However, it will structure not only the reducer itself but also your state. Each state that managed by distinct reducer will be separated into a deep object with a specified key.
Moreover, the combining logic should ideally focus on the combining only when creating the store. And each reducer should manage their own states as the default values of the first parameter. flatCombineReducers
allow us to give the initial state as default parameters. Thus, it could put the responsibility of each reducer in order.
You can pass an object to its last parameter to control the flatCombineReducers' behavior.
const options = { mergePrevState: false }
flatCombineReducers(reducerA, reducerB, options)
OptionName | DefaultValue | Description |
---|---|---|
mergePrevState |
true |
If true, the combined reducer will assign the returned state with the previous state. |
With its help, you can simplify your reducer logic and avoid the boilerplate likes Object.assign({}, state, PROCESSED_STATE)
From:
function reducerA(state = initialState, action) {
switch (action.type) {
case ACTION_TYPE_A:
return Object.assign({}, state, {
visibilityFilter: action.filter
});
default:
return state;
}
}
To:
function reducerA(state = initialState, action) {
switch (action.type) {
case ACTION_TYPE_A:
return {
visibilityFilter: action.filter
};
}
}
const reducer = flatCombineReducers();
expect(reducer({ A: 1, B: 2 }, "indifferentAction")).to.deep.equal({ A: 1, B: 2 });
expect(reducer({ A: 1, B: 2 })).to.deep.equal({ A: 1, B: 2 });
expect(reducer()).to.deep.equal({});
Note. You can change it by specifying the option mergePrevState
.
const reducer = flatCombineReducers(
(prevState, action) => ({A: prevState.A + action.value}),
(prevState, action) => ({B: prevState.B * action.value})
);
expect(reducer({ A: 1, B: 2 }, { value: 3 })).to.deep.equal({ A: 4, B: 6 });
const reducer = flatCombineReducers(
(prevState = { A: 1 }, action) => ({A: prevState.A + action.value}),
(prevState = { B: 2 }, action) => ({B: prevState.B * action.value})
);
expect(reducer(undefined, { value: 3 })).to.deep.equal({ A: 4, B: 6 });
const reducer = flatCombineReducers(
(prevState = { A: 1 }, action) => ({...prevState, A: prevState.A + action.value}),
(prevState = { A: 2 }, action) => ({...prevState, A: prevState.A * action.value})
);
expect(reducer(undefined, { value: 3 })).to.deep.equal({ A: 6 });
const reducer = flatCombineReducers(
(prevState, action) => ({A: prevState.A + action.value}),
{ mergePrevState: false }
);
expect(reducer({ A: 1, B: 2 }, { value: 3 })).to.deep.equal({ A: 4 });