Home > Net >  Redirect in react-router-dom V6
Redirect in react-router-dom V6

Time:12-15

I need to navigate back to the original requested URL after login.

For example, user enters www.example.com/settings as user is not authenticated, it will navigate to login page www.example.com/login.

Once authenticated, it should navigate back to www.example.com/settings automatically.

My original approach with react-router-dom v5 is quite simple:

const PrivateRoute = ({ isLoggedIn, component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) =>
        isLoggedIn? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{ pathname: `/login/${props.location.search}`, state: { from: props.location } }}
          />
        )
      }
    />
  );
};


<PrivateRoute exact isLoggedIn={isLoggedIn} path="/settings" component={Settings} />

Can some one tell me how to do that in v6? Thanks in advance

CodePudding user response:

You can pass the next page to your login url.

import { useLocation, useNavigate } from 'react-router-dom'

const PrivateRoute = ({ isLoggedIn, component: Component, ...rest }) => {
  const location = useLocation();
  const navigate = useNavigate();  
  return (
    <Route
      {...rest}
      render={(props) =>
        isLoggedIn? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{ pathname: `/login/${props.location.search}?next=${location.pathname}`, state: { from: props.location } }}
          />
        )
      }
    />
  );
};

Then in your login logic.

<button onClick={handleLogin}>Login</button>

async function handleLogin(){
    //check credentials
    //on success
    navigate(props.next, { replace: true });
}

This is how to approach your problem, my code my need some changes to fit your scenario.

CodePudding user response:

In react-router-dom v6 rendering routes and handling redirects is quite different than in v5. Gone are custom route components, they are replaced with a wrapper component pattern.

v5 - Custom Route

Takes props and conditionally renders a Route component with the route props passed through or a Redirect component with route state holding the current location.

const CustomRoute = ({ isLoggedIn, ...props }) => {
  const location = useLocation();
  return isLoggedIn? (
    <Route {...props} />
  ) : (
    <Redirect
      to={{
        pathname: `/login/${location.search}`,
        state: { location },
      }}
    />
  );
};

...

<PrivateRoute
  exact
  isLoggedIn={isLoggedIn}
  path="/settings"
  component={Settings}
/>

v6 - Custom Wrapper

Takes props and conditionally renders an Outlet component for nested Route components to be rendered into or a Navigate component with route state holding the current location.

const CustomWrapper = ({ isLoggedIn, ...props }) => {
  const location = useLocation();
  return isLoggedIn? (
    <Outlet />
  ) : (
    <Navigate
      to={`/login/${location.search}`}
      replace
      state={{ location }}
    />
  )
};

...

<Route path="settings" element={<CustomWrapper isLoggedIn={isLoggedIn} />} >
  <Route path="settings" element={<ProtectedSettings />} />
</Route>
  • Related