[v6] Split location from navigation to prevent unnecessary re-rendering
See original GitHub issueGood day!
The following is an idea, which would increase the performance of any app which is using react-router
. Please keep in mind, that some of the following assumptions could be wrong. This is also based on the v6
code.
Currently we have one combined context called LocationContext
, it stores:
interface LocationContextObject {
action?: Action;
location?: Location;
navigator?: Navigator;
static: boolean;
}
The ContextProvider
is the <Router>
component, which is also assigning those values here.
After taking a look at any Router implementation (MemoryRouter, BrowserRouter or HashRouter) I was seeing the same pattern, where the context updates:
let [state, setState] = React.useState({
action: history.action,
location: history.location
});
React.useLayoutEffect(() => history.listen(setState), [history]);
The context will update each time you navigate, but as you can see only the action
and the location
update, the navigator
remains unchanged. This is important, because many hooks
are depending on the LocationContext
but are only using the navigator
: useNavigate, useBlocker, useHref, and possibly more.
Yes I know, they’re using the useInRouterContext
hook which is depending on the location
, but this is only used to print error / warning messages and thus could be changed.
If there would be one context for location
(and action
) and one for navigation
, then components which would use hooks where only the navigation
is needed, would not update unnecessarily if the location
changes, since navigation
is static.
Actual Behavior
I noticed this behavior while experimenting with the router. Here is the Codesandbox example I did: https://codesandbox.io/s/charming-hooks-yotlj?file=/src/Admin.js
As you can see, the “renders” stay the same, no matter how many times you change the route. But as soon as I start using the useNavigate
hook, they increase with each navigation: https://codesandbox.io/s/peaceful-faraday-32xke?file=/src/Admin.js
Thanks for reading!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:6
- Comments:8 (1 by maintainers)
Fixed by #7936
Thanks for implementing to everyone involved! 😃