Built for developers, by XinhND

v2.1.0

Ready

React Router Cheat Sheet

Complete reference guide for React Router with interactive examples and live playground links

Installation & Setup

3 items

Install React Router
Basic Setup - Declarative Mode
Basic Setup - Data Mode

Routing Configuration

4 items

Basic Routes
Nested Routes
Dynamic Routes
+1 more items

Navigation Components

2 items

Link Component
NavLink with Active States

Router Hooks

3 items

useNavigate - Programmatic Navigation
useParams - Access URL Parameters
useLocation - Access Location Object

Search Parameters

3 items

useSearchParams - Basic Usage
useSearchParams - Setting Parameters
Tab Navigation with Search Params

Advanced Patterns

4 items

Route Protection
Conditional Redirects
Error Boundaries and 404 Routes
+1 more items

Best Practices

3 items

Lazy Loading Routes
Custom Hooks for Router Logic
Route-based Code Organization

Click on any section to jump directly to it

Installation & Setup

Install React Router

Install React Router package for your React application

React Router
# Install React Router v7 (latest)
npm install react-router

# Or with yarn
yarn add react-router

# Or with pnpm
pnpm add react-router

Basic Setup - Declarative Mode

Set up React Router in declarative mode with BrowserRouter

React Router
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./App";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

Basic Setup - Data Mode

Set up React Router in data mode with RouterProvider

React Router
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router";
import Home from "./components/Home";
import About from "./components/About";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />
  },
  {
    path: "/about",
    element: <About />
  }
]);

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <RouterProvider router={router} />
);

Routing Configuration

Basic Routes

Define basic routes using Routes and Route components

React Router
import { Routes, Route } from "react-router";
import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";

function App() {
  return (
    <Routes>
      <Route index element={<Home />} />
      <Route path="about" element={<About />} />
      <Route path="contact" element={<Contact />} />
    </Routes>
  );
}

Nested Routes

Create nested routes with parent-child relationship

React Router
import { Routes, Route, Outlet } from "react-router";

// Parent component with Outlet
function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <nav>
        <Link to="/dashboard">Home</Link>
        <Link to="/dashboard/settings">Settings</Link>
      </nav>
      <Outlet /> {/* Child routes render here */}
    </div>
  );
}

// App routes
function App() {
  return (
    <Routes>
      <Route path="dashboard" element={<Dashboard />}>
        <Route index element={<DashboardHome />} />
        <Route path="settings" element={<Settings />} />
      </Route>
    </Routes>
  );
}

Dynamic Routes

Handle dynamic URL segments and optional parameters

React Router
import { Routes, Route } from "react-router";

function App() {
  return (
    <Routes>
      {/* Single dynamic segment */}
      <Route path="users/:userId" element={<User />} />
      
      {/* Multiple dynamic segments */}
      <Route path="users/:userId/posts/:postId" element={<Post />} />
      
      {/* Optional segments */}
      <Route path="products/:id?" element={<Product />} />
      
      {/* Catch-all routes (splats) */}
      <Route path="files/*" element={<FileViewer />} />
    </Routes>
  );
}

Layout Routes

Use layout routes for shared UI without adding URL segments

React Router
function App() {
  return (
    <Routes>
      {/* Layout route without path adds nesting */}
      <Route element={<AuthLayout />}>
        <Route path="login" element={<Login />} />
        <Route path="register" element={<Register />} />
      </Route>
      
      {/* Another layout for protected routes */}
      <Route element={<ProtectedLayout />}>
        <Route path="dashboard" element={<Dashboard />} />
        <Route path="profile" element={<Profile />} />
      </Route>
    </Routes>
  );
}

Navigation Components

Link Component

Create navigation links with Link component

React Router
import { Link } from "react-router";

function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/contact">Contact</Link>
      
      {/* Link with state */}
      <Link to="/dashboard" state={{ from: 'navigation' }}>
        Dashboard
      </Link>
      
      {/* Relative links */}
      <Link to="../parent">Go to Parent</Link>
      <Link to="child">Go to Child</Link>
    </nav>
  );
}

NavLink with Active States

Use NavLink for navigation with active state styling

React Router
import { NavLink } from "react-router";

function Navigation() {
  return (
    <nav>
      {/* Automatic .active class */}
      <NavLink to="/">Home</NavLink>
      
      {/* Custom active styling with className */}
      <NavLink
        to="/about"
        className={({ isActive }) =>
          isActive ? "text-red-500 font-bold" : "text-black"
        }
      >
        About
      </NavLink>
      
      {/* Custom active styling with style */}
      <NavLink
        to="/contact"
        style={({ isActive }) => ({
          color: isActive ? 'red' : 'black',
          fontWeight: isActive ? 'bold' : 'normal'
        })}
      >
        Contact
      </NavLink>
      
      {/* Active children callback */}
      <NavLink to="/dashboard">
        {({ isActive }) => (
          <span className={isActive ? "active" : ""}>
            {isActive ? "👉" : ""} Dashboard
          </span>
        )}
      </NavLink>
    </nav>
  );
}

Router Hooks

useNavigate - Programmatic Navigation

Navigate programmatically using useNavigate hook

React Router
import { useNavigate } from "react-router";

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

  const handleSubmit = async (formData) => {
    try {
      await login(formData);
      
      // Navigate to dashboard after successful login
      navigate("/dashboard");
      
      // Navigate with replace (replaces current entry)
      navigate("/dashboard", { replace: true });
      
      // Navigate back
      navigate(-1);
      
      // Navigate forward
      navigate(1);
      
      // Navigate with state
      navigate("/profile", { 
        state: { message: "Login successful" } 
      });
      
    } catch (error) {
      console.error("Login failed:", error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* form fields */}
    </form>
  );
}

useParams - Access URL Parameters

Extract dynamic parameters from the current route

React Router
import { useParams } from "react-router";

// For route: /users/:userId/posts/:postId
function PostDetail() {
  const params = useParams();
  
  // Access individual parameters
  const { userId, postId } = useParams();
  
  // Or access all params
  console.log(params); // { userId: "123", postId: "456" }

  return (
    <div>
      <h1>Post {postId}</h1>
      <p>By User {userId}</p>
    </div>
  );
}

// For catch-all routes: /files/*
function FileViewer() {
  const { "*": splat } = useParams();
  // or
  const params = useParams();
  const filePath = params["*"];
  
  return <div>Viewing file: {filePath}</div>;
}

useLocation - Access Location Object

Access current location information and state

React Router
import { useLocation } from "react-router";

function LocationInfo() {
  const location = useLocation();
  
  console.log(location.pathname);  // "/dashboard/settings"
  console.log(location.search);    // "?tab=general&page=2"
  console.log(location.hash);      // "#section1"
  console.log(location.state);     // state passed via navigate
  console.log(location.key);       // unique key for this location

  return (
    <div>
      <h2>Current Path: {location.pathname}</h2>
      <p>Query String: {location.search}</p>
      {location.state && (
        <p>State: {JSON.stringify(location.state)}</p>
      )}
    </div>
  );
}

// Common use cases
function useAnalytics() {
  const location = useLocation();
  
  useEffect(() => {
    // Track page views
    analytics.track(location.pathname);
  }, [location]);
}

function ScrollToTop() {
  const location = useLocation();
  
  useEffect(() => {
    window.scrollTo(0, 0);
  }, [location.pathname]);
  
  return null;
}

Search Parameters

useSearchParams - Basic Usage

Read URL search parameters using useSearchParams

React Router
import { useSearchParams } from "react-router";

function SearchResults() {
  const [searchParams, setSearchParams] = useSearchParams();
  
  // Get individual search parameter
  const query = searchParams.get("q");
  const page = searchParams.get("page") || "1";
  const category = searchParams.get("category");
  
  // Check if parameter exists
  const hasFilter = searchParams.has("filter");
  
  // Get all entries
  const allParams = Object.fromEntries(searchParams.entries());
  console.log(allParams); // { q: "react", page: "2", category: "tech" }

  return (
    <div>
      <h1>Search Results for: {query}</h1>
      <p>Page: {page}</p>
      <p>Category: {category || "All"}</p>
    </div>
  );
}

useSearchParams - Setting Parameters

Update URL search parameters while preserving existing ones

React Router
import { useSearchParams } from "react-router";

function ProductFilters() {
  const [searchParams, setSearchParams] = useSearchParams();
  
  const activeCategory = searchParams.get("category") || "all";
  const activeSort = searchParams.get("sort") || "name";
  const currentPage = parseInt(searchParams.get("page") || "1");

  // Update single parameter (replaces all params)
  const setCategory = (category) => {
    setSearchParams({ category });
  };

  // Update multiple parameters (replaces all params)
  const applyFilters = (category, sort) => {
    setSearchParams({
      category,
      sort,
      page: "1" // reset to first page
    });
  };

  // Preserve existing params while updating
  const setPage = (page) => {
    const newParams = new URLSearchParams(searchParams);
    newParams.set("page", page.toString());
    setSearchParams(newParams);
  };

  // Remove a specific parameter
  const removeFilter = (paramName) => {
    const newParams = new URLSearchParams(searchParams);
    newParams.delete(paramName);
    setSearchParams(newParams);
  };

  return (
    <div>
      <select 
        value={activeCategory}
        onChange={(e) => setCategory(e.target.value)}
      >
        <option value="all">All Categories</option>
        <option value="electronics">Electronics</option>
        <option value="clothing">Clothing</option>
      </select>
      
      <button onClick={() => setPage(currentPage + 1)}>
        Next Page
      </button>
    </div>
  );
}

Tab Navigation with Search Params

Use search params for tab navigation and state management

React Router
import { useSearchParams } from "react-router";

function TabNavigation() {
  const [searchParams, setSearchParams] = useSearchParams();
  const activeTab = searchParams.get('tab') || 'overview';

  const setActiveTab = (tab) => {
    const newParams = new URLSearchParams(searchParams);
    newParams.set('tab', tab);
    setSearchParams(newParams);
  };

  const tabs = [
    { id: 'overview', label: 'Overview' },
    { id: 'details', label: 'Details' },
    { id: 'reviews', label: 'Reviews' },
  ];

  return (
    <div>
      {/* Tab Navigation */}
      <div className="tab-nav">
        {tabs.map(tab => (
          <button
            key={tab.id}
            className={`tab ${activeTab === tab.id ? 'active' : ''}`}
            onClick={() => setActiveTab(tab.id)}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* Tab Content */}
      <div className="tab-content">
        {activeTab === 'overview' && <OverviewContent />}
        {activeTab === 'details' && <DetailsContent />}
        {activeTab === 'reviews' && <ReviewsContent />}
      </div>
    </div>
  );
}

Advanced Patterns

Route Protection

Implement route protection and authentication guards

React Router
import { Navigate, useLocation } from "react-router";
import { useAuth } from "./hooks/useAuth";

function ProtectedRoute({ children }) {
  const { user } = useAuth();
  const location = useLocation();

  if (!user) {
    // Redirect to login with return URL
    return (
      <Navigate 
        to="/login" 
        state={{ from: location }} 
        replace 
      />
    );
  }

  return children;
}

// Usage in routes
function App() {
  return (
    <Routes>
      <Route path="/login" element={<Login />} />
      <Route path="/public" element={<PublicPage />} />
      
      {/* Protected routes */}
      <Route
        path="/dashboard"
        element={
          <ProtectedRoute>
            <Dashboard />
          </ProtectedRoute>
        }
      />
      
      {/* Or using layout route */}
      <Route element={<ProtectedRoute />}>
        <Route path="/profile" element={<Profile />} />
        <Route path="/settings" element={<Settings />} />
      </Route>
    </Routes>
  );
}

Conditional Redirects

Implement conditional redirects based on application state

React Router
import { Navigate } from "react-router";

function Dashboard() {
  const { user, loading } = useAuth();
  
  if (loading) {
    return <LoadingSpinner />;
  }

  // Redirect based on user role
  if (user?.role === 'admin') {
    return <Navigate to="/admin-dashboard" replace />;
  }

  if (user?.role === 'manager') {
    return <Navigate to="/manager-dashboard" replace />;
  }

  return <UserDashboard />;
}

// Conditional redirect in routes
function App() {
  return (
    <Routes>
      <Route 
        path="/dashboard" 
        element={
          user?.isFirstLogin ? 
            <Navigate to="/onboarding" /> : 
            <Dashboard />
        } 
      />
    </Routes>
  );
}

Error Boundaries and 404 Routes

Handle 404 errors and implement catch-all routes

React Router
import { Routes, Route } from "react-router";

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      
      {/* Nested routes with error handling */}
      <Route path="/products" element={<ProductsLayout />}>
        <Route index element={<ProductsList />} />
        <Route path=":id" element={<ProductDetail />} />
        
        {/* Catch-all for products section */}
        <Route path="*" element={<ProductNotFound />} />
      </Route>
      
      {/* Global 404 route - must be last */}
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

// Custom 404 component
function NotFound() {
  const location = useLocation();
  
  return (
    <div>
      <h1>Page Not Found</h1>
      <p>The page `{location.pathname}` does not exist.</p>
      <Link to="/">Go Home</Link>
    </div>
  );
}

URL State Management

Manage complex application state through URL parameters

React Router
import { useSearchParams, useNavigate } from "react-router";

function ProductList() {
  const [searchParams, setSearchParams] = useSearchParams();
  const navigate = useNavigate();
  
  // Parse complex state from URL
  const filters = {
    category: searchParams.get('category') || 'all',
    minPrice: parseInt(searchParams.get('minPrice') || '0'),
    maxPrice: parseInt(searchParams.get('maxPrice') || '1000'),
    tags: searchParams.get('tags')?.split(',') || [],
    sortBy: searchParams.get('sortBy') || 'name',
    page: parseInt(searchParams.get('page') || '1'),
  };

  // Update URL state
  const updateFilters = (newFilters) => {
    const params = new URLSearchParams();
    
    Object.entries({ ...filters, ...newFilters }).forEach(([key, value]) => {
      if (value !== null && value !== undefined && value !== '') {
        if (Array.isArray(value)) {
          if (value.length > 0) {
            params.set(key, value.join(','));
          }
        } else {
          params.set(key, value.toString());
        }
      }
    });
    
    setSearchParams(params);
  };

  // Reset all filters
  const clearFilters = () => {
    navigate(location.pathname, { replace: true });
  };

  return (
    <div>
      <FilterPanel 
        filters={filters} 
        onFiltersChange={updateFilters}
        onClearFilters={clearFilters}
      />
      <ProductGrid filters={filters} />
    </div>
  );
}

Best Practices

Lazy Loading Routes

Implement code splitting and lazy loading for better performance

React Router
import { lazy, Suspense } from "react";
import { Routes, Route } from "react-router";

// Lazy load components
const Dashboard = lazy(() => import("./components/Dashboard"));
const Settings = lazy(() => import("./components/Settings"));
const Profile = lazy(() => import("./components/Profile"));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
        <Route path="/profile" element={<Profile />} />
      </Routes>
    </Suspense>
  );
}

// Or create a wrapper component
function LazyRoute({ children }) {
  return (
    <Suspense fallback={<LoadingSpinner />}>
      {children}
    </Suspense>
  );
}

Custom Hooks for Router Logic

Create reusable custom hooks for common routing patterns

React Router
import { useLocation, useNavigate } from "react-router";

// Custom hook for breadcrumbs
export function useBreadcrumbs() {
  const location = useLocation();
  
  const pathSegments = location.pathname
    .split('/')
    .filter(Boolean)
    .map((segment, index, array) => ({
      name: segment.charAt(0).toUpperCase() + segment.slice(1),
      path: '/' + array.slice(0, index + 1).join('/'),
    }));
    
  return [{ name: 'Home', path: '/' }, ...pathSegments];
}

// Custom hook for navigation with confirmation
export function useNavigateWithConfirmation() {
  const navigate = useNavigate();
  
  return (to, options = {}) => {
    const shouldNavigate = options.skipConfirmation || 
      window.confirm('Are you sure you want to leave this page?');
      
    if (shouldNavigate) {
      navigate(to, options);
    }
  };
}

// Custom hook for query string management
export function useQueryParams() {
  const [searchParams, setSearchParams] = useSearchParams();
  
  const setParam = (key, value) => {
    const params = new URLSearchParams(searchParams);
    params.set(key, value);
    setSearchParams(params);
  };
  
  const removeParam = (key) => {
    const params = new URLSearchParams(searchParams);
    params.delete(key);
    setSearchParams(params);
  };
  
  const getParam = (key, defaultValue = null) => {
    return searchParams.get(key) || defaultValue;
  };
  
  return { setParam, removeParam, getParam, searchParams };
}

Route-based Code Organization

Organize routes and components in a scalable file structure

React Router
// File structure
src/
  routes/
    index.tsx              // Route definitions
    guards/
      ProtectedRoute.tsx
      AdminRoute.tsx
    layouts/
      AppLayout.tsx
      AuthLayout.tsx
    pages/
      Home/
        index.tsx
        components/
        hooks/
      Dashboard/
        index.tsx
        components/
        hooks/

// routes/index.tsx
import { createBrowserRouter } from "react-router";
import AppLayout from "./layouts/AppLayout";
import ProtectedRoute from "./guards/ProtectedRoute";
import { lazy } from "react";

const Home = lazy(() => import("./pages/Home"));
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Profile = lazy(() => import("./pages/Profile"));

export const router = createBrowserRouter([
  {
    path: "/",
    element: <AppLayout />,
    children: [
      {
        index: true,
        element: <Home />
      },
      {
        path: "dashboard",
        element: (
          <ProtectedRoute>
            <Dashboard />
          </ProtectedRoute>
        )
      },
      {
        path: "profile",
        element: (
          <ProtectedRoute>
            <Profile />
          </ProtectedRoute>
        )
      }
    ]
  }
]);

React Router - Interactive Developer Reference

Hover over code blocks to copy or run in live playground