Usable mainly when reducer is more like assembler for your data store changes, and main logic is put into action. So you often need to dispatch multiple smaller action, but to keep it atomic, they have to be processed in a single reduce step. This is the solution. The bonus is, it works well with devTools also.
export function multipleActionsEnhanceReducer(reducer) {
return (state, action, ...rest) => {
if (action.actions && action.actions.type && action.actions instanceof Array) {
state = action.actions.reduce(reducer, state);
} else {
state = reducer(state, action);
}
return state;
};
}
export function multipleActionsEnhanceDispatch(dispatch) {
return (action) => {
var multipleAction;
if (action instanceof Array) {
if (action.type === undefined) {
action.type = action.map((a) => a.type).join(' => ');
}
multipleAction = {
type: action.type,
actions: action
};
}
return dispatch(multipleAction || action);
};
}
export function multipleActionsEnhancer() {
return (next) => (reducer, initialState) => {
var store = next(multipleActionsEnhanceReducer(reducer), initialState);
store.dispatch = multipleActionsEnhanceDispatch(store.dispatch);
return store;
};
}
const createStoreFinal = compose(
multipleActionsEnhancer(), // allows store to process array of actions synchronously
devTools()
)(createStore);
const store = createStoreFinal(statisticsReducer);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('stores/reducers/statistics', () => {
const nextRootReducer = require('stores/reducers/statistics');
store.replaceReducer(multipleActionsEnhanceReducer(nextRootReducer)); // HERE
});
}
Then we can dispatch actions like:
return function multipleBatchedActions() {
return [
{
type: ACTION1,
payload: {
...
}
}, {
type: ACTION2,
payload: {
...
}
}
]
}
And all these actions are processed synchronously and as single atomic operation.