Blogged Answers: A Comparison of Redux Batching Techniques

This is a post in the Blogged Answers series.

An explanation of the various options for batching actions in Redux

The Redux FAQ has an entry on "how to reduce the number of store update events". This ties into the somewhat common question of "how do I batch actions with Redux?".

There's a Redux issue from 2016 where a user tried to suggest changing dispatch to accept multiple action arguments at once. That PR was rejected because the attempted implementation failed to consider how the changes would interact with the rest of the ecosystem, and because solutions could be implemented in userland.

There's multiple tools and approaches available for "batching" with Redux, and they all work at different levels and in different ways. During that discussion, I did a bunch of research on how Redux actually behaves and how these libraries implement forms of batching.

I'll summarize the major options:

  • redux-batched-actions: a higher-order reducer that wraps multiple sub-actions in a larger "BATCH" action. If you pass multiple actions to the batchActions action creator, it creates a new action that puts the array of actions as the payload. The higher-order reducer wraps around your "real" reducer, looks for that type : "BATCH" action, and calls your "real" reducer repeatedly with each action in the array. Since the higher-order reducer is only being executed once, from the store's perspective it's all one action being handled by one call to the reducer, so there's only one notification. However, this limits how things like middleware might interact with the dispatched actions, and also makes it harder to read them in the DevTools.
  • redux-batched-subscribe: A store enhancer that wraps the real store's dispatch method. It allows you to provide your own subscriber notification callback, which might use something like _.debounce() or React's unstable_batchedUpdates() API to limit how many times the UI actually attempts to re-render when multiple actions are dispatched in close sequence.
  • redux-batch: a store enhancer that wraps the store's dispatch and subscribe methods. It allows you to pass an array of actions to dispatch, passes them to the real store's dispatch one at a time, but then only notifies subscribers once the entire array has been processed. This allows the individual actions to still show up in the DevTools separately, but only results in a single notification event.
  • React-Redux's batch API: this is just React's unstable_batchedUpdates() API, re-exported and renamed. It allows you to provide a callback where multiple React state updates are queued, but only have a single render pass as a result. If you're dispatching Redux actions inside, each dispatched action would still result in a separate notification of subscribers (and running of mapState functions), but the rendering would get combined.

So, it's really a question of what your goal is for "batching actions", and where you want the modification of the process to occur. Given the variety of use cases, you can see why we chose not to implement anything like this directly in the Redux core - there's just too many different use cases, and they can be handled in userland.

That means that if you're using redux-batched-actions and redux-saga together, you'd have to specifically be watching for the "BATCH" action type in your sagas, rather than looking for the specific individual action types, and you'd have to unpack those actions yourself. If you're using redux-batch, on the other hand, I think you should be able to listen for the individual actions as normal.

This is a post in the Blogged Answers series. Other posts in this series:

Author Avatar

Mark Erikson

Collector of interesting links, answerer of questions