[Bug]: useNavigate function triggers constant rerender when used in useEffect
See original GitHub issueWhat version of React Router are you using?
6.0.2
Steps to Reproduce
In ReactRouter 6.0.0.beta2 the following code worked and executed only when isAuthenticated changed.
export const AppRouter = () => {
const { isAuthenticated } = useAuthenticatedUser();
const navigate = useNavigate();
const routes = useRoutes(APP_ROUTES);
useEffect(() => {
if (isAuthenticated) {
navigate("Dashboard");
} else {
navigate("Login");
}
}, [isAuthenticated, navigate]);
return <Suspense fallback={<LoadingPage />}>{routes}</Suspense>;
};
also this snippet ran useEffect only when activeUser.id changed:
export const Users = () => {
const { activeUser } = useActiveUser();
const navigate = useNavigate();
useEffect(() => {
if (activeUser.id) {
navigate(`${activeUser.name}/${activeUser.view}`);
}
if (activeUser.id === '') {
navigate(``);
}
}, [navigate, activeUser]);
return (
<ContentWithDrawer drawerContent={<UsersNav />}>
<Suspense fallback={<ContentLoading loading={true} Icon={AccountCircleIcon} withFade={false} />}>
<Routes>
<Route path=":name/*" element={<UsersContent />} />
<Route path="" element={<ContentLoading loading={false} Icon={AccountCircleIcon} />} />
</Routes>
</Suspense>
</ContentWithDrawer>
);
};
In the current version a re-render is triggered every time navigate() is called somewhere in the App.
This is, I assume, caused by one of the dependencies in the dependecy array of navigate's useCallback. Everytime navigate is called a dependency changes and forces useCallback to create a new function and in the process kill referential equality of navigate which triggers the useEffect. This is just a wild guess because this is one of the main differences that I noticed in a quick overview of useNavigate between 6.0.0-beta.2 vs 6.0.2. I also checked 6.0.0-beta.3. and this behavior exists since then.
Expected Behavior
When navigate function of useNavigate is used as a useEffect dependecy the referential-equality of navigate should be ensured on every route change.
Actual Behavior
The navigate function of useNavigate triggers useEffect on every route change.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:8 (1 by maintainers)
Top Related StackOverflow Question
I created a small provider that prevents updates from router context for this.
And in your app — add this provider below Router
@chrishoermann I don’t think devs should have to choose between an “ABSOLUTE” nav style and buggy rendering. Why not simply fix the bug? See my comment on this duplicate issue for a bugfix:
https://github.com/remix-run/react-router/issues/7634#issuecomment-1013806084