Home > database >  Redirect to last browser history location in React
Redirect to last browser history location in React

Time:02-08

I am working on my personal React project. The React app has a login page. After successfully logging in, the user is redirected to homepage i.e. on path / . And if the user again tries to navigate to login page i.e. path /login , then the user will be redirected back to homepage

The app also has protected route on path /profile which is accessible only if the user is authenticated.

But the problem is, when the user navigates to protected route and then refreshes the page, it is redirecting to the homepage. How can I make it redirect back to the same protected route from where the user had refreshed?

Here is Login.js

// Login.js
      if (isUserLoggedIn) {
        return <Redirect to="/" />;
      }
      // else render login page

And here is ProtectedRoute.js

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { Redirect, Route } from "react-router";

export default function ProtectedRoute({ component: Component, ...rest }) {
  
  const { isUserLoggedIn } = useSelector((state) => state.common);

  return (
    <Route
      {...rest}
      render={(props) =>
        !isUserLoggedIn ? <Redirect to="/login" /> : <Component {...props} />
      }
    />
  );
}

And this is how I'm getting the value of isUserLoggedIn from cookies and then setting it to the Redux state.

 const [authenticated] = useState(() =>
    Boolean(Number(Cookies.get("isUserLoggedIn")))
  );
  useEffect(() => {
    if (!authenticated) {
      return dispatch({
        type: NOT_AUTHENTICATED,
      });
    } else {
      return dispatch({
        type: AUTHENTICATED,
      });
    }
  }, [authenticated]);

CodePudding user response:

In simpler terms, you will have to make the browser remember that the user is now authenticated. That can be simply achieved by adding a specific token or isValid = true to the session storage and then you will have to use the value from session storage as your reference.

Updating user status in the state cannot persist it on reload. You would have to use persistor then. However, the easier way is to update session storage.

You can create a new JS file, say session.js and create the following functions:

export const setToken = (value) => {
    sessionStorage.setItem('token', value)
}

export const getToken = () => {
    return sessionStorage.getItem('token') || null
}

export const removeToken = () => {
    sessionStorage.removeItem('token')
}

You can call setToken(true) on successful authentication and remove the token removeToken() on log out. You can then call getToken() to check your user's authentication in your if statement. I hope it helps!

CodePudding user response:

It happened same with me. I have solved this problem by using a variable that will be in Local storage so when siging in also set localstorage variable isLogged to true localStorage.setItem("isLogged", true) so in case he is already logged and refreshed the page the user will redirected to profile page. The switch statement is used bacause we get string value from localstorage and we have to convert it to boolean

function App() {
  const token = localStorage.getItem("isLogged");
  let auth = null;
  switch (token) {
    case "true":
      auth = true;
      break;
    case "false":
      auth = false;
      break;

    default:
      break;
  }}

as the code above you can now pass the variable auth to the component in protected route like this

<PrivateRoute
          path="/main"
          component={Main}
          isAuthenticated={auth}
        ></PrivateRoute>

and in the Private Route Component add the isAuthenticated props

const PrivateRoute = ({ component: Component, isAuthenticated, ...props }) => {
  return (
    <Route
      {...props}
      render={(props) =>
        isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
            }}
          />
        )
      }
    />
  );
};

This is the Login Component

const Login = () => {
  const history = useHistory();

  async function onSubmit(data) {
    try {
      await signin(data.userName, data.password);
      localStorage.setItem("isLogged", true);
      toast.success("Registerd successfully");
      history.go("/main");
    } catch {
      toast.error("Error");
    }
  }

  return (
    <div className="form-container">
      <img src={Logo} alt="logo" className="logo-img"></img>
      <h1>Login to Your Account</h1>
      <Form onSubmit={onSubmit} className="form-items">
        {({ handleSubmit }) => (
          <form onSubmit={handleSubmit}>
            <Field name="userName">
              {({ input }) => (
                <TextField
                  name="userName"
                  type="input"
                  id="standard-basic"
                  label="user Name"
                  variant="standard"
                  fullWidth
                  {...input}
                />
              )}
            </Field>
            <Field name="password">
              {({ input }) => (
                <TextField
                  name="password"
                  type="password"
                  id="standard-basic"
                  label="Password"
                  variant="standard"
                  fullWidth
                  {...input}
                />
              )}
            </Field>
            <Button
              type="submit"
              sx={{
                width: "100%",
                backgroundColor: "rgba(56, 211, 159, 255)",
                marginTop: "40px",
                color: "white",
              }}
            >
              Login
            </Button>
            <div>
              Don't Have an Account <Link to="/register">Sign up</Link>
            </div>
          </form>
        )}
      </Form>
    </div>
  );
};
  •  Tags:  
  • Related