Maximum update depth exceeded from Navigate component react-router-dom v6
I'm using react-router-dom v6
to control the route of my React Js app.
Here are the specifications:
-
I'm creating the
AuthenticationRoute
andPrivateRoute
components. -
The
AuthenticationRoute
component is used to wrap pages that the user doesn't need to authenticate for examplesSignIn
,SignUp
,ForgotPassword
, andResetPassword
pages. -
The
PrivateRoute
component is used to wrap private pages (authentication is needed) for example Home page. Inside thePrivateRoute
, there are some layouts. One of them is called theDashboard
layout to wrap theDrawer
(Sidebar/Navigation) component and theHome
page. -
If the user has not logged in via the
SignIn
page, the app would return theSignIn
page. If the user has logged in, the app would return theHome
page.
Here are the current conditions:
Note: The check sign (✅) represents the conditions I want while the cross sign (❌) represents the error or unwanted conditions.
-
All of the specifications above are met. ✅
-
The first time user runs the app, the
SignIn
page is returned because the user has not logged in. ✅ -
If the user has not logged in and typed "/" route to the address bar (to access the
Home
page) via theSignIn
page, the app will not redirect the user to theHome
page instead of returning theSignIn
page. ✅ -
If the user successfully logged in via the
SignIn
page, the app would return theHome
page (with "/" route). ✅ -
If the user has logged in and typed "/sign-in" route to the address bar (to access the
SignIn
page) via theHome
page, the app return error: ❌
Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
at Navigate (https://5xxrw.csb.app/node_modules/react-router/index.js:247:12)
at AuthenticationRoute (https://5xxrw.csb.app/src/components/Routes/AuthenticationRoute.jsx:21:26)
at Routes (https://5xxrw.csb.app/node_modules/react-router/index.js:306:18)
at App
at Router (https://5xxrw.csb.app/node_modules/react-router/index.js:266:18)
at BrowserRouter (https://5xxrw.csb.app/node_modules/react-router-dom/index.js:284:18)
The app should navigate back the user to the Home
page ("/" route) instead of returning the error.
Here is the code for the AuthenticationRoute
:
function AuthenticationRoute(props) {
const { children } = props;
const userProfile = readUserProfileFromLocalStorage();
return userProfile ? <Navigate replace to="/sign-in" /> : children;
}
and here is the code for the PrivateRoute
:
function PrivateRoute(props) {
const { children } = props;
const userProfile = readUserProfileFromLocalStorage();
return userProfile ? (
<Dashboard>{children}</Dashboard>
) : (
<Navigate replace to="/sign-in" />
);
}
Here is the playground: https://codesandbox.io/s/stackoverflow-auth-private-routes-5xxrw
I did a similar thing using react-router-dom v5
but didn't return the error. Everything was fine.
So, what's the solution for this case?
There is an issue on your AuthenticationRoute
component. You are redirecting the user to /sign-in
when userProfile
is defined, which causes an infinite loop since its the same page. It should be navigating to /
function AuthenticationRoute(props) {
const { children } = props;
const userProfile = readUserProfileFromLocalStorage();
return userProfile ? <Navigate replace to="/" /> : children;
}