React Router

  • React Router is the industry-standard library for managing navigation and routing in React applications.
  • It transforms a Single Page Application (SPA) into a multi-page experience by mapping browser URLs to specific components.
  • By keeping the UI in sync with the URL, it enables features like bookmarking, deep linking, and using the browser's back/forward buttons without reloading the entire page.
Developer Tip: React doesn't come with built-in routing because it is a library, not a full-blown framework like Angular. React Router fills this gap, making it an essential tool for almost every production-grade React project.

Installation

To get started, you need to install the react-router-dom package, which contains the DOM-specific bindings for React Router. Use npm or yarn in your project terminal:

npm install react-router-dom

or

yarn add react-router-dom
Best Practice: Always use react-router-dom for web applications. The core react-router package is a dependency of the DOM version, so you don't need to install both manually.

Basic Example

In modern React Router (v6+), we wrap our application in a BrowserRouter. We then use Routes to contain individual Route definitions. To move between pages without a page refresh, we use the Link component instead of standard anchor tags.

import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

const Home = () => <h2>Home Dashboard</h2>;
const About = () => <h2>About Our Team</h2>;

const App = () => {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
          </ul>
        </nav>

        {/* The Routes container manages which component displays based on the URL */}
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </div>
    </Router>
  );
};

export default App;
Common Mistake: Using a standard HTML <a href="/about"> tag. This will cause the entire browser to reload, wiping out your React state. Always use the <Link> component to keep the "Single Page" experience intact.

Route Parameters

In many applications, you need to display dynamic data based on an ID, such as a product page or a user profile. React Router uses the colon (:) syntax to define dynamic segments in a URL path. You can then access these values using the useParams hook.

import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link, useParams } from 'react-router-dom';

const User = () => {
  // Extract the "id" parameter from the URL
  const { id } = useParams();
  return <h2>Displaying Profile for User ID: {id}</h2>;
};

const App = () => {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li><Link to="/user/123">View User 123</Link></li>
            <li><Link to="/user/456">View User 456</Link></li>
          </ul>
        </nav>

        <Routes>
          <Route path="/user/:id" element={<User />} />
        </Routes>
      </div>
    </Router>
  );
};

export default App;
Watch Out: Route parameters are always returned as strings. If you need to use the id for a mathematical operation or a strict comparison, remember to convert it using parseInt(id, 10) or Number(id).

Nested Routes

Nested routing is useful when a portion of the UI remains constant (like a sidebar) while the inner content changes based on the sub-path. In modern React Router, we define nested Route components and use the <Outlet /> component to tell the parent where the child should be rendered.

import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link, Outlet } from 'react-router-dom';

const Dashboard = () => (
  <div>
    <h2>Admin Dashboard</h2>
    <nav>
      <Link to="profile">My Profile</Link> | <Link to="settings">Settings</Link>
    </nav>
    <hr />
    {/* This is where the nested child component will appear */}
    <Outlet />
  </div>
);

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />}>
          <Route path="profile" element={<h3>User Profile Content</h3>} />
          <Route path="settings" element={<h3>Account Settings Content</h3>} />
        </Route>
      </Routes>
    </Router>
  );
};
Developer Tip: Notice that child paths in nested routes don't need a leading slash (/). Writing path="profile" inside a /dashboard route automatically resolves to /dashboard/profile.

Redirects

Redirecting users is a common requirement for authentication or handling old URLs. In modern React Router, we use the <Navigate /> component to trigger a redirect declaratively, or the useNavigate hook to do so programmatically (e.g., after a login button is clicked).

import React, { useState } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';

const PrivateRoute = ({ children }) => {
  const [isAuthenticated] = useState(false); // Example auth state

  // If not logged in, redirect to the login page
  return isAuthenticated ? children : <Navigate to="/login" replace />;
};

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/login" element={<h2>Please Login</h2>} />
        <Route 
          path="/dashboard" 
          element={
            <PrivateRoute>
              <h2>Sensitive Dashboard Data</h2>
            </PrivateRoute>
          } 
        />
      </Routes>
    </Router>
  );
};
Best Practice: When redirecting after an action like a logout, use { replace: true }. This replaces the current entry in the history stack, preventing the user from clicking the "back" button and returning to a restricted page.

 

Summary

React Router is much more than just a way to switch components; it's a powerful state management tool for the URL. By mastering Basic Routes, Dynamic Parameters, and Nested Layouts, you can build complex, enterprise-ready navigation systems. As you grow, explore the useNavigate and useLocation hooks to gain even finer control over your application's flow.