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
dispatchmethod. It allows you to provide your own subscriber notification callback, which might use something like
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
subscribemethods. It allows you to pass an array of actions to
dispatch, passes them to the real store's
dispatchone 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.
batchAPI: 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
mapStatefunctions), 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-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:
- Aug 02, 2017 - Blogged Answers: Webpack HMR vs React-Hot-Loader
- Dec 18, 2017 - Blogged Answers: Resources for Learning React
- Dec 18, 2017 - Blogged Answers: Resources for Learning Redux
- Mar 29, 2018 - Blogged Answers: Redux - Not Dead Yet!
- Jan 19, 2019 - Blogged Answers: Debugging Tips
- Jul 10, 2019 - Blogged Answers: Thoughts on React Hooks, Redux, and Separation of Concerns
- Nov 26, 2019 - Blogged Answers: Learning and Using TypeScript as an App Dev and a Library Maintainer
- Jan 01, 2020 - Blogged Answers: A Comparison of Redux Batching Techniques
- Jan 01, 2020 - Blogged Answers: Reasons to Use Thunks
- Jan 01, 2020 - Blogged Answers: Years in Review, 2018-2019
- Jan 19, 2020 - Blogged Answers: React, Redux, and Context Behavior