Elassoa
Elassoa

Reputation: 143

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

Upvotes: 1

Views: 16914

Answers (2)

Elassoa
Elassoa

Reputation: 143

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

Upvotes: 3

Flo
Flo

Reputation: 3127

First of all: in your app.js you say: if auth == true then show signup/signin. auth needs to be false in this case. then add a new route path="*" and redirect it to signup as example. Then in your SignUp component in the useEffect function you say: come from SignIn then.... "ELSE" (and here is the error) you say:

    setAuth(false);
    history.goBack();

So you set setAuth to false. In this case you can never navigate back from page 2 to page 1 as example. This page are only visible if auth is true.

Greetings, Flo

Upvotes: 1

Related Questions