Module: Routing

Routes and Links

Routing is a fundamental aspect of building multi-page applications with React. It allows users to navigate between different views or components without a full page reload, providing a smoother and more dynamic user experience. React Router is the most popular library for handling routing in React applications.

Core Concepts

  • Routes: Define the mapping between a URL path and a React component. When the browser's URL matches a route's path, the corresponding component is rendered.
  • Links: Used to navigate between routes. Instead of using standard <a href="..."> tags, React Router provides the <Link> component. This prevents full page reloads and leverages React's component rendering.
  • BrowserRouter (or HashRouter): Wraps your application and enables routing functionality. BrowserRouter uses the browser's history API (clean URLs), while HashRouter uses the hash portion of the URL (e.g., your-app.com/#/about). BrowserRouter is generally preferred for production.
  • Routes: A container for individual Route components. It ensures that only the first matching route is rendered.
  • Route: Defines a single route, specifying the path and the component to render when that path is matched.
  • useNavigate: A hook that provides access to the navigation object, allowing programmatic navigation.

Implementation with React Router v6

Here's a basic example demonstrating how to set up routing with React Router v6:

1. Installation:

npm install react-router-dom
# or
yarn add react-router-dom

2. App.js (or your main application component):

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

function Home() {
  return (
    <div>
      <h2>Home</h2>
      <p>Welcome to the homepage!</p>
    </div>
  );
}

function About() {
  return (
    <div>
      <h2>About</h2>
      <p>Learn more about us.</p>
    </div>
  );
}

function Contact() {
  return (
    <div>
      <h2>Contact</h2>
      <p>Get in touch with us.</p>
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/contact">Contact</Link>
          </li>
        </ul>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Explanation:

  • BrowserRouter: Wraps the entire application, enabling routing.
  • Link: Creates navigation links. The to prop specifies the path to navigate to.
  • Routes: Contains the individual Route components.
  • Route: Each Route component defines a path and the component to render when that path is matched. The element prop specifies the component.

Dynamic Routes (Route Parameters)

To create routes that accept parameters (e.g., /products/:id), you can use dynamic segments in the path:

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

function ProductDetail() {
  let { productId } = useParams(); // Access the 'id' parameter

  return (
    <div>
      <h2>Product Detail</h2>
      <p>Product ID: {productId}</p>
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/products/123">Product 123</Link>
          </li>
          <li>
            <Link to="/products/456">Product 456</Link>
          </li>
        </ul>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products/:productId" element={<ProductDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Explanation:

  • /products/:productId: The :productId is a dynamic segment. It will match any value in that position.
  • useParams(): A hook that allows you to access the values of the dynamic segments in the URL. In this case, productId will contain the value of the id parameter.

Programmatic Navigation with useNavigate

The useNavigate hook allows you to navigate programmatically within your components:

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

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

  const handleSubmit = (event) => {
    event.preventDefault();
    // Simulate login success
    navigate('/dashboard'); // Navigate to the dashboard after login
  };

  return (
    <div>
      <h2>Login</h2>
      <form onSubmit={handleSubmit}>
        {/* Login form fields */}
        <button type="submit">Login</button>
      </form>
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/login">Login</Link>
          </li>
        </ul>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/dashboard" element={<div>Dashboard</div>} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Explanation:

  • useNavigate(): Returns a navigation object.
  • navigate('/dashboard'): Programmatically navigates to the /dashboard route.

Nested Routes

You can create nested routes to represent hierarchical relationships in your application:

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

function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
      <ul>
        <li><Link to="overview">Overview</Link></li>
        <li><Link to="settings">Settings</Link></li>
      </ul>
      <Routes>
        <Route path="overview" element={<div>Dashboard Overview</div>} />
        <Route path="settings" element={<div>Dashboard Settings</div>} />
      </Routes>
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/dashboard">Dashboard</Link>
          </li>
        </ul>
      </nav>

      <Routes>
        <Route path="/" element={<div>Home</div>} />
        <Route path="/dashboard" element={<Dashboard />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Explanation:

  • The Dashboard component has its own Routes and Route components, defining sub-routes within the dashboard.
  • The Link components within Dashboard use relative paths (e.g., to="overview") to navigate within the dashboard's routes.

Resources

This provides a solid foundation for understanding and implementing routing in your React applications. Remember to consult the official React Router documentation for more advanced features and options.