The react-redux
package relies on the rendering engine of react
/react-dom
to trigger the re-render of a given component that uses the useSelector
hook.
If you take a look at the source of useSelector
you can notice the use of useReducer
:
const [, forceRender] = useReducer((s) => s + 1, 0)
As the name (forceRender
) implies, redux uses this to trigger a re-render by react.
With v8
of react-redux
the implementation of this mechanism changes but still relies on react-hooks for the re-render.
If you are curious how React handles re-renders, take a look at this excellent SO answer. It provides a great entry on the implementation details of how react-hooks are associated with the calling component.
I don't repeat Ryan here, but to sum it up:
The renderer keeps a reference to the component that is currently rendered. All hooks being executed during this render (no matter how deeply nested in custom-hooks they are) ultimately belong to this component.
So, the useReducer
is associated with the component within which you called useSelector
.
The dispatch function of useReducer
triggers a re-render of this component (React either calls the render()
method of a class-component or executes the function body of a functional component).
If you are curious how react-redux
determines when it should force this re-render (by utilizing useReducer
), take another look at the source code of useSelector
.
Redux uses the subscriber-pattern to get notified of updates to the state. If the root-state of redux is updated the following things happen:
useSelector
hooks in your application re-run their selector function
- This re-selected state is compared to the previously selected state (by default via
===
comparison). The second argument to useSelector
can be a comparison function to change this behavior
- If the re-selected state differs from the previously selected state, a re-render is triggered via the
useReducer
hook.
The subscriber pattern is very react-like but potentially helps save many re-renders. Calling several useSelector
hooks is cheap when compared with re-renders.