Mike K
Mike K

Reputation: 6521

How to redirect user back to initially-requested page after authentication with React-Router v6?

I have a situation where, if a user isn't authenticated, they get redirected to the login page.

Once the user logs in, they get sent back to the main page.

This is a pretty typical situation with React, but I'm wondering how I can redirect the user back to a certain page after they authenticate.

Suppose the user tries to access /app/topics, which would be a private route. They would get redirected to /, where they have to authenticate. Afterwards, they get redirected to /app/about once they authenticated.

How can I ensure that the user gets redirected back to /app/topics instead?


The About component would look something like,

const About = ({ user }) => {
  const navigate = useNavigate();

  React.useEffect(() => {
    if (!user) navigate("/");
  }, [user]);
  return (
    <div>
      <h2>About</h2>
    </div>
  );
};

export default About;

And Home (or the 'login page') would look like this,

const Home = ({ user, setUser }) => {
  const navigate = useNavigate();

  React.useEffect(() => {
    if (user) navigate("/app/about");
  }, [user]);

  return (
    <div>
      <h2>Login</h2>
      <input />
      <button onClick={() => setUser(1)}>login</button>
    </div>
  );
};

export default Home;

I'm aware the this line,

if (user) navigate("/app/about");

Is why the user gets redirected to About upon authenticating, but I'm wondering how I can change this up, so that the user is redirected back to Topics.


I've tried a combination of different approached. The most promising thing that I've tried was saving the requested uri into my Redux state. This cause issue with my existing code, however.

I've also tried saving state with Navigate or useNavigate.

If I recall correctly, React-Router v5 had a redirect prop or something of the sort, that redirected the user back to a certain page.

react-router-forked-pjer0?

Upvotes: 2

Views: 1504

Answers (2)

LIIT
LIIT

Reputation: 604

React router v6 documentation provides an exemple that answers you requirements, here is their sandbox.

They use the from property of location's state:

function LoginPage() {
  let navigate = useNavigate();
  let location = useLocation();
  let auth = useAuth();

  let from = location.state?.from?.pathname || "/";

  function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();

    let formData = new FormData(event.currentTarget);
    let username = formData.get("username") as string;

    auth.signin(username, () => {
      // Send them back to the page they tried to visit when they were
      // redirected to the login page. Use { replace: true } so we don't create
      // another entry in the history stack for the login page.  This means that
      // when they get to the protected page and click the back button, they
      // won't end up back on the login page, which is also really nice for the
      // user experience.
      navigate(from, { replace: true });
    });
  }

Upvotes: 0

Luk&#225;š Gibo Vaic
Luk&#225;š Gibo Vaic

Reputation: 4420

I would just fallback to good old query parametr in url, just upon redirecting to login page, put query param, from or something in url, and upon successfull login do the redirect, this has the huge advatage that if you take him to different page or for some reason he has to reload page, he keeps this info.

Upvotes: 1

Related Questions