Skip to content

Instantly share code, notes, and snippets.

@gt3
Forked from Aldredcz/multipleActionEnhancer.md
Created December 27, 2018 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gt3/c72878ea30bf7d77337c5a77d3b528f2 to your computer and use it in GitHub Desktop.
Save gt3/c72878ea30bf7d77337c5a77d3b528f2 to your computer and use it in GitHub Desktop.
Redux - enhance store to process multiple batched actions

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.

Sourcecode:

multipleActionEnhancer.js:

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;
	};
}

Top-level Component setup:

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
	});
}

Example:

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment