Here I’m trying to navigate to "/home" route using useNavigate() hook right after the login request is successful. Instead of routing to ‘/home’, its reloading the "/login".
Here I’m attaching code
App.js
export default function App() {
const router = createBrowserRouter([{
path: '/',
element: isUserValid() ? <Navigate to="/home" replace /> : <Navigate to="/login" replace />,
errorElement: <Error />
},
{
path: '/login',
element: !isUserValid() ? <Login /> : <Navigate to="/home" replace />
}, {
path: '/register',
element: !isUserValid() ? <Register /> : <Navigate to="/home" replace />
},
{
path: '/home',
element: isUserValid() ? <Form /> : <Navigate to="/login" replace />
}])
return (
<RouterProvider router={router} />
)
}
In the above isUserValid()
returns true or false based on the session maintained in localStorage.
Login.js
const handleSubmit = async (e) => {
const isValid = onSubmit(e);
if (isValid) {
const payLoad = {};
for (let key in formData) {
payLoad[key] = formData[key]['value'];
}
try {
const response = await login(payLoad);
localStorage.setItem('user', JSON.stringify(response.data));
debugger;
console.log("//== before navigation")
navigate('/home', { replace: true });
} catch (err) {
console.log("inside login error");
setApiErrorMessage(err.response.data.error);
}
}
}
The above code is for form submission, I’m able to get the token from the backend and able to store it in localStorage.
Here is the problem occures, I’m unable to re route to ‘/home’. Please provide me a solution.
2
Answers
Since setting to local storage is an asynchronous operation, navigation might be taking place before value is set to local storage and the
isUserValid
function might be returning false, hence redirecting to login.It looks like you might be running into a race condition where the route is being updated before the isUserValid() function can read the updated local storage value. To resolve this issue, you can use a state management solution like React context or Redux to manage the user’s authentication status. For simplicity, I’ll show you an example using React context.
First, create a new file named AuthContext.js:
Now, update your App.js to use the AuthProvider:
Update the routes in App.js to use the useAuth() hook:
Finally, update your Login.js to use the login function from the AuthContext:
By using a context, you can manage the authentication status more effectively and avoid race conditions caused by reading from local storage. This should resolve the issue you’re experiencing.