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>