Redirects & Programmatic Navigation in React Router Explained

When users interact with your app — for example, after logging in, submitting a form, or clicking a button — you often need to redirect them to another page automatically.

In React Router, this is called programmatic navigation, and it’s powered by the useNavigate() hook.

Instead of relying on links (<Link> or <NavLink>), useNavigate() lets you navigate through code — perfect for handling actions, logins, or conditional routing.

What Is Programmatic Navigation?

Programmatic navigation means navigating between routes using JavaScript logic instead of manually clicking a link.

Example scenarios:

  • Redirect users after successful login.

  • Navigate to a detail page when an item is clicked.

  • Go back to the previous page after completing an action.

  • Redirect unauthorized users to a login page.

The useNavigate() Hook

useNavigate() is a hook from react-router-dom that returns a function you can call to change routes dynamically.

 Import

 
import { useNavigate } from "react-router-dom";

 Basic Usage

function Home() {
  const navigate = useNavigate();

  const goToAbout = () => {
    navigate("/about");
  };

  return (
    <div>
      <h2>🏠 Home Page</h2>
      <button onClick={goToAbout}>Go to About</button>
    </div>
  );
}

Explanation:

  • useNavigate() gives you a navigate function.

  • Calling navigate("/about") redirects the user to /about without reloading the page.

Navigating with Parameters

You can dynamically build URLs based on data.

function Products() {
  const navigate = useNavigate();

  const handleViewProduct = (id) => {
    navigate(`/product/${id}`);
  };

  return (
    <div>
      <h2>🛒 Product List</h2>
      <button onClick={() => handleViewProduct(101)}>View Product 101</button>
      <button onClick={() => handleViewProduct(102)}>View Product 102</button>
    </div>
  );
}

Result:
Clicking “View Product 101” → Navigates to /product/101.

Passing State Between Routes

You can pass extra data (like user info, form data, etc.) using the state parameter.

function Login() {
  const navigate = useNavigate();

  const handleLogin = () => {
    navigate("/dashboard", { state: { user: "John Doe" } });
  };

  return (
    <div>
      <h2>🔐 Login Page</h2>
      <button onClick={handleLogin}>Login</button>
    </div>
  );
}

function Dashboard({ location }) {
  const locationData = location?.state;
  console.log(locationData?.user); // "John Doe"

  return <h2>Welcome, {locationData?.user}!</h2>;
}

Explanation:

  • navigate("/dashboard", { state: { user: "John Doe" } }) passes temporary data to the destination route.

  • Access it via useLocation() inside the target component.

Example Using useLocation()

import { useLocation } from "react-router-dom";

function Dashboard() {
  const location = useLocation();
  const { user } = location.state || {};

  return <h2>Welcome, {user || "Guest"}!</h2>;
}

Redirecting After an Action (e.g., Login)

function Login() {
  const navigate = useNavigate();

  const handleLogin = (event) => {
    event.preventDefault();
    // Simulate authentication
    const isAuthenticated = true;

    if (isAuthenticated) {
      navigate("/dashboard");
    } else {
      navigate("/login");
    }
  };

  return (
    <form onSubmit={handleLogin}>
      <h2>🔑 Login Form</h2>
      <button type="submit">Login</button>
    </form>
  );
}

Redirects to /dashboard after successful login.

Replacing History (No Back Navigation)

By default, navigation adds a new entry to the browser history.
Use { replace: true } to prevent going back to the previous page.

 
navigate("/dashboard", { replace: true });

 Useful after login or logout so users can’t go back to the login screen.

Go Back, Forward & Custom History

useNavigate() also supports relative navigation:

 
navigate(-1); // Go back navigate(1); // Go forward

Example

function ProductPage() {
  const navigate = useNavigate();

  return (
    <div>
      <h2>📦 Product Details</h2>
      <button onClick={() => navigate(-1)}>⬅️ Go Back</button>
    </div>
  );
}

This mimics browser navigation buttons directly in your React app.

Redirect Component Alternative

In React Router v6, the <Redirect /> component has been replaced by <Navigate />.

Example

import { Navigate } from "react-router-dom";

function ProtectedRoute({ isAuthenticated, children }) {
  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }
  return children;
}

Use <Navigate /> when you want conditional redirection in JSX,
and useNavigate() when you want redirection inside a function.

Conditional Redirect Example

function Checkout() {
  const navigate = useNavigate();
  const isCartEmpty = true;

  if (isCartEmpty) {
    navigate("/cart", { replace: true });
  }

  return <h2>Proceeding to Checkout</h2>;
}

Prevents navigation to checkout when cart is empty.

Best Practices

  • Use useNavigate() for button clicks, form submissions, and API actions.
  • Use <Navigate /> for conditional redirects inside route elements.
  • Use { replace: true } for post-login or post-logout flows.
  • Keep URL paths centralized in a route configuration file for consistency.