reactjsroutesreact-routerreact-router-domhistory.js

Switching pages with history.push() passing state - React Router 5


I want to switch between pages.
I'm pushing path and a {state} object.
The problem is that when pressing the browser back button its going endless back and forth between Signup and Signin even though I switch only twice or more.

Or when pressing the browser back button the URL changes to signin or signup but the page will be my 404 component, or to the Main page (in the sandbox) regardless what was the page before.

codesandbox

The two components are in a conditional rendering

 {auth ? (
          <Switch>
            <Route path="/signup" auth={auth}>
              <SignUp setAuth={setAuth} />
            </Route>
            <Route path="/signin" auth={auth}>
              <SignIn setAuth={setAuth} />
            </Route>
          </Switch>
        ) : 

when switching from signup to signin in a button -

history.push({
          pathname: "/signin",
          state: { from: "fromSignUp" }
        });

Pressing the browser back button on each component will check in the history if it came from signup or signin -

useEffect(() => {
    window.onpopstate = () => {
      console.log("useEffect SignUp", location.state?.from === "fromSignIn"); // sometimes true/sometimes false, even when came from 'signin'
      if (location.state?.from === "fromSignIn") {
        history.push({
          pathname: "/signin",
          state: { from: "fromSignUp" }
        });
      } else {
        setAuth(false);
        history.goBack();
      }
    };
  }, [location.state, history]);

In my VS Code its acting even worse .

I can give a link to the GitHub repository.

Thanks


Solution

  • Solution found.
    Thanks to a friend of mine I found that don't need any of this conditions, functions and push() -

    Removed -
    const [auth setAuth] = useState(false)  // no need
    
     window.onpopstate = () => {   // no need
     history.push({    // no need
              pathname: "/signin",
              state: { from: "fromSignUp" }
            });
    

    The solution is with two per of <Switch>. The Route's closing tag for Header (the navbar) - <Route> <Header/> - </Route> is below all other components inside the inner Switch

    I'm not showing the props here.
    App.js

      return (
        <div>
          <Switch>
            <Route path="/signup">
              <SignUp />
            </Route>
            <Route path="/signin">
              <SignIn />
            </Route>
            <Route >
              <Header />
              <div>
                <Switch>
                  <Route exact path="/"  >
                    <Main />
                  </Route>
                  <Route path="/pageone" >
                    <PageOne />
                  </Route>
                  <Route path="/pagetwo"  >
                    <PageTwo />
                  </Route>
                  <Route component={PageNotFound} path="*" />
                </Switch>
              </div>
            </Route>
          </Switch>
        </div>
      );
    

    All works as it should, Perfect. Thanks to David