In interstellar space, we sometimes need to immediately redirect our ship to another course. In the world of React Router, redirects work similarly - they allow us to transfer the user from one path to another automatically.
The simplest way to create a redirect is to use the
Navigate component from React Router:1import { Navigate } from 'react-router-dom';
2
3function RedirectToControl() {
4 return <Navigate to="/control-center" />;
5}When this component is rendered, the user will be automatically redirected to the specified path. This is a declarative way of redirecting - you simply place the component in the JSX tree.
We often need to redirect the user only under certain conditions, for example when they are not logged in:
1function SecretMoonBase() {
2 const isAstronaut = useAuth();
3
4 if (!isAstronaut) {
5 return <Navigate to="/access-denied" replace />;
6 }
7
8 return (
9 <div>
10 <h1>Secret Moon Base</h1>
11 <p>Welcome astronaut! You have access to classified data.</p>
12 </div>
13 );
14}The
replace attribute causes the redirect to replace the current page in the browser history, instead of adding a new one. This way the user won't end up back on the protected page after clicking the "back" button.Sometimes we need to redirect the user in response to some event, like a form submission. We use the
useNavigate hook for this:1import { useNavigate } from 'react-router-dom';
2
3function LaunchControlForm() {
4 const navigate = useNavigate();
5
6 const handleLaunch = (event) => {
7 event.preventDefault();
8 // Launch preparation logic...
9
10 // Redirect to the countdown page
11 navigate('/countdown');
12
13 // Or with the replace parameter
14 // navigate('/countdown', { replace: true });
15 };
16
17 return (
18 <form onSubmit={handleLaunch}>
19 <h2>Launch Control Panel</h2>
20 <button type="submit">Start Countdown</button>
21 </form>
22 );
23}React Router allows us to easily handle the case when a user tries to visit a path that doesn't exist:
1<Routes>
2 <Route path="/mission-control" element={<MissionControl />} />
3 <Route path="/navigation" element={<Navigation />} />
4 <Route path="*" element={<Navigate to="/lost-in-space" />} />
5</Routes>The
* path matches any route that doesn't match any of the previous ones. Instead of Navigate, we can also render a 404 component:1<Route path="*" element={<LostInSpace />} />We can also pass additional data during a redirect:
1// Declarative redirect with parameters
2<Navigate
3 to="/asteroid-alert"
4 state={{ severity: "high", location: "sector-7" }}
5/>
6
7// Programmatic redirect with parameters
8navigate('/asteroid-alert', {
9 state: { severity: "high", location: "sector-7" }
10});In the target component, we can read this data using the
useLocation hook:1import { useLocation } from 'react-router-dom';
2
3function AsteroidAlert() {
4 const location = useLocation();
5 const { severity, location: asteroidLocation } = location.state || {};
6
7 return (
8 <div className="alert">
9 <h1>Asteroid Warning!</h1>
10 {severity && asteroidLocation && (
11 <p>
12 Asteroid detected with {severity} threat level at location {asteroidLocation}.
13 </p>
14 )}
15 </div>
16 );
17}The most common use case for redirects is protecting routes from unauthorized users:
1function ProtectedRoute({ children }) {
2 const { user, loading } = useAuth();
3
4 if (loading) {
5 return <LoadingSpinner />;
6 }
7
8 if (!user) {
9 // Redirect to login page saving the original path
10 return <Navigate to="/login" state={{ from: location.pathname }} />;
11 }
12
13 return children;
14}
15
16// Usage:
17<Routes>
18 <Route path="/mission-control" element={
19 <ProtectedRoute>
20 <MissionControl />
21 </ProtectedRoute>
22 } />
23</Routes>On the login page, we can read the original path and redirect back after login:
1function Login() {
2 const navigate = useNavigate();
3 const location = useLocation();
4 const from = location.state?.from || '/dashboard';
5
6 const handleLogin = async (credentials) => {
7 const success = await loginUser(credentials);
8
9 if (success) {
10 // Redirect back to the original page
11 navigate(from, { replace: true });
12 }
13 };
14
15 // Rest of the component...
16}Redirects are a powerful tool in React applications using React Router. They allow for:
Remember to use the
replace parameter when you want to prevent the user from returning to the previous page using the "back" button - this is especially important in the case of login pages and other authentication scenarios.