In react-redux v7, we now have the useDispatch()
hook to get a reference to the store dispatch. See here: https://react-redux.js.org/api/hooks#usedispatch
The resulting dispatch
function then needs to be listed as a dependency for any useEffect
, useMemo
, etc. hooks. Why is this?
After some testing, the app still works perfectly fine without dispatch
being listed as a dependency, so I can only assume it's not changing.
Is there any case where the dispatch
function could change?
Redux is most useful in cases when:You have large amounts of application state that are needed in many places in the app. The app state is updated frequently. The logic to update that state may be complex. The app has a medium or large-sized codebase, and might be worked on by many people.
dispatch() is a more logical and better approach to dispatching actions in Redux than using store. dispatch() directly, as it makes sure that your Redux store does not become a singleton module. Most of the time, dispatch() is called from within the store consuming components and, similar to this.
The fact that the Redux state changes predictably opens up a lot of debugging possibilities. For example, using time travel makes it possible to travel back and forth between different states instead of having to reload the whole app in order to get back to the same place.
Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.
There's two answers to this.
First, as far as I know, the React "rules of hooks" ESLint rule knows how to handle the built-in hooks specially. For example, it knows that useState()
always returns the same setter function instance, so you don't have to include that in a useEffect()
dependency array (ditto for the dispatch
function from a useReducer()
call).
However, the lint rule doesn't know about custom hooks, whether they be from a library or your own. So, since useDispatch()
is a custom hook, the lint rule has to assume that whatever this dispatch
thing is could change, and tries to tell you that you need to list it as a dependency.
The second answer is that it's possible to pass a new store reference to <Provider>
, in which case there's a different store.dispatch
being returned from the useDispatch()
hook.
So, realistically, the code will run fine without including dispatch
in the deps array, because your app is almost definitely using the same store instance the entire time. But, since the lint rule doesn't know that, you will probably need to include it in the list anyway to make it be quiet.
(Source: I'm a Redux maintainer, and helped guide the implementation of our hooks API :) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With