T
TanStack2y ago
equal-aqua

Issue with Navigation in Protected Routes v1.1.5

Hello Community, I'm working with v1.1.5 and encountering an issue related to navigation in protected routes. This problem seems to be connected to the handling of authentication state, particularly when a simulated delay is introduced during the login process. I'm unsure if this is an issue with React's internal behavior, Zustand state management, or my implementation. Any guidance or suggestions would be really highly valuable. Context: - Implementing protected routes in a Vite React application. - Managing authentication state using Zustand and React Context. - Experiencing different navigation behaviors based on the presence of a simulated delay in the login process. - Uncertainty about the Meta way of implementing Protected Routes using the library Issue Description: - Without the delay, the application navigates correctly to the protected dashboard after login. - With the delay, the router does not navigate as expected after login. That I have to click again, or refresh page that it would read from the local storage. - When setToken is called with a delay(asnycronously) the AuthContext updates which triggers a rerender, but router is not updated according to this. and the user is stuck at the login page where the user is in fact logged in, and if the user clicks again or refreshes the page then the user navigates to the dashboard page Thank you for your time and assistance!
No description
No description
No description
No description
No description
No description
No description
No description
12 Replies
other-emerald
other-emerald2y ago
can we see what setIsLoading is doing? e.g. where/how is isLoading used (assuming this is a useState)
equal-aqua
equal-aquaOP2y ago
It's useState
No description
other-emerald
other-emerald2y ago
oh actually i think i see what's happening. once they're in the login page, the only thing that would cause them to be redirected is if beforeLoad ran again, right? and it wont, because the route didnt change ^ to verify if above is the issue, try putting this in the login page component:
const { isLoggedIn } = useAuth()
const navigate = useNavigate()

useEffect(() => {
if (isLoggedIn) {
navigate({ to: "/" })
}
}, [isLoggedIn, navigate])
const { isLoggedIn } = useAuth()
const navigate = useNavigate()

useEffect(() => {
if (isLoggedIn) {
navigate({ to: "/" })
}
}, [isLoggedIn, navigate])
maybe some typos in there but you get the idea
equal-aqua
equal-aquaOP2y ago
Thank you for your suggestion. I tried implementing the useEffect hook with navigation logic inside the login component. This solution worked successfully! It appears that the root of the issue lies in the beforeLoad function not being re-triggered, as the route doesn't change when the Auth Context updates. However, I'm still a bit puzzled about the specifics of this behavior. When the setToken function is called without any asynchronous action, the ProtectedRoute component renders correctly, checking the isLoggedIn status. But, when setToken involves an asynchronous action (like a simulated delay), this expected behavior doesn't occur. To illustrate this, I've attached two additional screenshots showing the render cycles with and without the delay in setToken. Could this be related to how the React Router handles context changes, or is it something specific about how asynchronous actions interact with the routing and state?
No description
No description
equal-aqua
equal-aquaOP2y ago
First ss is when login occurs after a delay, second when login occurs immediatly
other-emerald
other-emerald2y ago
i cant see where setToken is called. in onSubmit?
equal-aqua
equal-aquaOP2y ago
It's called on the parent
No description
equal-aqua
equal-aquaOP2y ago
These router methods can be skipped tbh
other-emerald
other-emerald2y ago
not sure what the simulated delay looks like but possibly it caused setToken and router.history.push() to be called in the wrong order. if that's not it then 🤷‍♀️ i'm stumped one other thing to check: are you using ReactDOM.createRoot or the legacy ReactDOM.render to render your app? the latter does not batch state updates in async functions, which could be causing some unexpected ordering of things when you go from sync -> async
equal-aqua
equal-aquaOP2y ago
I actually converted from a simulated settimeout delay to calling an external api to delay and still the same, I'm also stumped. I will look into at some later point probably since it doesn't seem to me that the state should be changed by useState to me when I have the context 😕 . I use ReactDOM.createRoot btw react v18.2
No description
other-emerald
other-emerald2y ago
very odd 😕 sorry i cant be more help. at least you have a workaround with useEffect? 😅
equal-aqua
equal-aquaOP2y ago
Haha yes, It's working! thanks for the help! If I find the root cause I will post here 🙂

Did you find this page helpful?