Skip to Content
Lesson 7

React Router

Workplace Context

In modern web development, Single Page Applications (SPAs) are prevalent. SPAs provide a fluid user experience by dynamically updating content without full page reloads. However, this means the browser’s default navigation (based on new HTML document requests) doesn’t work out-of-the-box. React Router is the de facto standard routing library for React, enabling developers to build SPAs with navigable “pages” or views, each associated with a unique URL. Understanding routing is crucial for creating intuitive and well-structured multi-view applications that users can easily navigate and share links to.


Learning Objectives

By the end of this lesson, you will be able to:

  • Understand the role of client-side routing and React Router in SPAs.
  • Install and set up React Router in a React project.
  • Implement basic routing using <BrowserRouter>, <Routes>, and <Route>.
  • Create navigation links using the <Link> and <NavLink> components.
  • Utilize the useNavigate hook for programmatic navigation.
  • Define and access route parameters using the useParams hook.
  • Be aware of advanced concepts like nested routes and layout components.

Introduction to React Router

React Router is a powerful routing library for React that allows you to manage navigation in your application. It enables you to define different “pages” or views and associate them with specific URLs. When a user navigates to a URL, React Router ensures the correct component is rendered without requiring a full page refresh from the server. This is known as client-side routing.

Installation

To start using React Router, you need to add it to your project. You can do this using npm or yarn:

npm install react-router-dom

or

yarn add react-router-dom

The react-router-dom package includes bindings for using React Router in web applications.

Setting Up React Router

The first step is to make React Router’s context available to your component tree. This is typically done by wrapping your root application component (e.g., App.js) with the <BrowserRouter> component.

import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode> );

Core Components

React Router provides several core components to define your application’s routing structure.

<BrowserRouter>

<BrowserRouter> uses the HTML5 History API (pushState, replaceState, and the popstate event) to keep your UI in sync with the URL. As shown above, it should typically wrap your entire application.

<Routes>

The <Routes> component is a container for a collection of <Route> components. It intelligently picks the best <Route> to render based on the current URL. When the location changes, <Routes> looks through all its child <Route> elements to find the best match and renders that branch of the UI.

<Route>

A <Route> component defines a mapping between a URL path and a React component that should be rendered when that path is matched.

  • path prop: A string representing the URL path to match (e.g., "/about", "/users/:userId").
  • element prop: The React element/component to render when the path matches (e.g., <AboutPage />).
import React from 'react'; import { Routes, Route, Link } from 'react-router-dom'; // Placeholder components for demonstration const HomePage = () => <h2>Home Page</h2>; const AboutPage = () => <h2>About Page</h2>; const ContactPage = () => <h2>Contact Page</h2>; const NotFoundPage = () => <h2>404 - Page Not Found</h2>; function App() { return ( <div> <nav> {/* Navigation links will be added here */} </nav> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> <Route path="/contact" element={<ContactPage />} /> <Route path="*" element={<NotFoundPage />} /> {/* Fallback for unmatched routes */} </Routes> </div> ); } export default App;

In the example above, path="*" acts as a catch-all route, often used for displaying a “404 Not Found” page.


React Router provides components and hooks for navigating between routes.

The <Link> component is the primary way to allow users to navigate around your application. It renders an <a> tag with a proper href attribute, but it handles the navigation client-side.

  • to prop: A string or object representing the target path (e.g., "/profile", {{ pathname: '/profile', search: '?sort=name' }}).
// Inside your App.js or a Navigation component <nav> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> </nav>

<NavLink> is a special type of <Link> that can style itself as “active” when its to prop matches the current URL. This is useful for highlighting the current page in a navigation menu.

It accepts style and className props that can be functions. These functions receive an object with an isActive boolean property.

import { NavLink } from 'react-router-dom'; // ... <NavLink to="/messages" style={({ isActive }) => ({ color: isActive ? 'red' : 'black', })} > Messages </NavLink> <NavLink to="/tasks" className={({ isActive }) => isActive ? 'active-link' : 'inactive-link'} > Tasks </NavLink>

useNavigate Hook

The useNavigate hook gives you access to a function that you can use to navigate programmatically, for instance, after a form submission or a state change.

import { useNavigate } from 'react-router-dom'; function MyComponent() { const navigate = useNavigate(); const handleSubmit = () => { // ... perform some action navigate('/dashboard'); // Navigate to /dashboard }; const goToPrevious = () => { navigate(-1); // Navigate to the previous page in history } return ( <div> <button onClick={handleSubmit}>Submit and Go to Dashboard</button> <button onClick={goToPrevious}>Go Back</button> </div> ); }

Route Parameters

Often, you need to capture dynamic segments in the URL, like a user ID or a product slug. React Router allows you to define route parameters in your path prop.

Example: /users/:userId where :userId is the parameter.

useParams Hook

The useParams hook returns an object of key/value pairs of URL parameters. Use it to access the matched parameters for the current <Route>.

// ... other imports import { useParams } from 'react-router-dom'; const UserProfilePage = () => { const { userId } = useParams(); // userId matches :userId in the path return <h2>User Profile: {userId}</h2>; }; function App() { // ... return ( // ... <Routes> <Route path="/" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> <Route path="/contact" element={<ContactPage />} /> <Route path="/users/:userId" element={<UserProfilePage />} /> {/* Dynamic route */} <Route path="*" element={<NotFoundPage />} /> </Routes> // ... ); }

If the URL is /users/123, useParams() in UserProfilePage would return { userId: "123" }. Note that URL parameters are always strings.


Advanced Concepts

React Router is very powerful and offers more advanced features that you might explore as your application grows:

  • Nested Routes: Allows you to define routes that are children of other routes. This is useful for creating complex UI layouts where parts of the UI (like a sidebar) are shared across multiple sub-views. An <Outlet /> component is used in parent routes to render their child route elements.
  • Layout Components (Layout Routes): A common pattern where a parent route acts as a layout wrapper (e.g., containing a header, footer, and navigation) and renders child routes within its structure using <Outlet />.
  • Protected Routes (Authentication): Implementing routes that require user authentication before they can be accessed.
  • Search Parameters (useSearchParams): For reading and modifying the query string in the URL.
  • Location (useLocation): Provides information about the current URL (pathname, search, hash).

These concepts build upon the fundamentals covered in this lesson and are key to building sophisticated SPAs.


Activity 1: Build a Basic Multi-Page Application

Objective: Create a simple React application with Home, About, and Products pages using React Router.

Instructions:

  1. Set up a new React project or use an existing one.
  2. Install react-router-dom.
  3. Create three components: HomePage, AboutPage, and ProductsPage.
  4. In your main App component:
    • Wrap your application with <BrowserRouter>.
    • Set up a navigation bar using <Link> components to navigate between these pages.
    • Define routes using <Routes> and <Route> to render the appropriate component for /, /about, and /products.
  5. Ensure clicking the links correctly changes the view without a full page reload.

Activity 2: Implement Route Parameters for Product Details

Objective: Extend the previous application to display details for a specific product using route parameters.

Instructions:

  1. Create a ProductDetailPage component.
  2. Modify the ProductsPage component:
    • Display a list of sample products (e.g., “Product 1”, “Product 2”).
    • Each product name should be a <Link> that navigates to a unique URL for that product, like /products/1, /products/2.
  3. In your App component, add a new route: <Route path="/products/:productId" element={<ProductDetailPage />} />.
  4. In the ProductDetailPage component:
    • Use the useParams hook to extract the productId from the URL.
    • Display the productId (e.g., “Details for Product: [productId]”).
  5. Verify that navigating to a product detail URL shows the correct product ID.

Knowledge Check

What is the primary purpose of React Router in a Single Page Application (SPA)?

  • Select an answer to view feedback.

Which set of components is essential for defining basic routes in React Router?

  • Select an answer to view feedback.

What is the React Router component used to create navigation links that enable client-side transitions?

  • Select an answer to view feedback.

Which hook is used for programmatic navigation in React Router (e.g., navigating after a form submission)?

  • Select an answer to view feedback.

How do you access dynamic segments from the URL path (e.g., a user ID from '/users/:userId') within a component rendered by a <Route>?

  • Select an answer to view feedback.

In React Router v6, how do you typically define a 'catch-all' or '404 Not Found' route?

  • Select an answer to view feedback.

Summary

React Router is an essential library for building SPAs with React. It allows you to create a rich, navigable user experience by mapping URLs to specific components. Key takeaways include:

  • Wrapping your app in <BrowserRouter>.
  • Using <Routes> to define a collection of possible routes.
  • Defining individual routes with <Route path="..." element={...} />.
  • Navigating with <Link> (declarative) and useNavigate (programmatic).
  • Accessing dynamic URL segments with useParams.

Mastering these concepts will enable you to build well-structured and user-friendly React applications.


References

Additional Resources