skip to Main Content

I’m currently working on a React project and trying to implement a proper login page. Therefore I created my LoginPage.tsx and another page, that should only be accessible if logged in.
I tried the following code

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Navigate to={"/other"}/>}/>
    <Route path="/other" element={loggedIn ? <OtherPage/>: <Navigate to={"/login"}/> }/>
    <Route path="/login" element={<LoginPage/>}/>
  </Routes>
</BrowserRouter>

The redirect to the LoginPage works perfectly fine, and by using
navigate("/other"); inside my LoginPage component after login, I’m redirected to OtherPage.
However, when using navigate(-1); (to go back one page) I always end up on the LoginPage.

Looking in the browser history, it seems that it never "saved" "/other" as visited url.
Is this normal? And how would I solve this problem?

It may be relevant to mention, that i use a redux store for loggedIn, and dispatch true after login at the LoginPage. Note that that’s not my actual code, as it is more complex and I’m not actually saving a login boolean in redux, rather than something else, but the principle is the same.

After trying to work on an example (https://codesandbox.io/s/reactrouter-login-rq0079?file=/src/App.tsx), it seems like the problem is something else. The codesandbox works just perfectly fine. After trying out a few things, it seems that in my real project, the rerender of my router component (there is also some other stuff that is set there) causes multiple "/login" in the history?
As my first guess, that react router dom doesn’t work correctly in STRICT mode, won’t work out, as the codesandbox runs also in STRICT mode. However, when running react in production mode, it works fine.
So I’m really confused there.
Is this normal behaviour of react router dom on rerender? Should the router component even rerender?

2

Answers


  1. Chosen as BEST ANSWER

    After a little time trying to replicate my bug on codesandbox I finally figured out what the problem was, or at least how to fix it. While working on codesandbox, I realised, that the version number of react-router-dom was different (I used 6.8.1, while codesandbox was using 6.8.2).

    Then I updated my version and it suddenly worked just fine. Seems like react-router-dom v6.8.1 has some struggles with the behaviour of React.StrictMode, as it added all URLs twice to the history (as mentioned later in my question). Atleast that's what i believe.

    Nevertheless, thx @Drew Reese for your help and I hope that others with that problem will find the solution faster than me :)


  2. It looks like you are issuing a PUSH navigation action from the login page. This will keep "/login" in the history stack. The user will be able to navigate back to "/login" from "/other" after logging in.

    You likely want to issue another REPLACE navigation action from the LoginPage to the OtherPage route. This will replace the "/login" entry in the history stack with "/other". If the user issues a back navigation from here they will navigate back to the page prior to the page they were on when they got redirected to authenticate.

    navigate("/other", { replace: true });
    

    I see that you also are using a PUSH action to navigate to "/login" in the case of unauthenticated users. Here, too, you’ll want to redirect instead of navigating to help maintain the history stack.

    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Navigate to="/other" replace />} />
        <Route
          path="/other"
          element={loggedIn ? <OtherPage />: <Navigate to="/login" replace />}
        />
        <Route path="/login" element={<LoginPage />} />
      </Routes>
    </BrowserRouter>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search