Instagram
youtube
Facebook
Twitter

Dynamic Routing

Introduction

Dynamic routing in React Router allows you to create routes that change based on specific parameters, such as a user ID or product ID, making your application more interactive and flexible. With dynamic routes, you can build pages that render different content based on the URL parameters, such as profile pages, product details, or blog posts. Dynamic routing is essential for applications that require personalized or unique pages for each user or item.

In this lesson, you’ll learn:

  • How to set up dynamic routes in React Router
  • How to access route parameters
  • Examples of common use cases for dynamic routes

What is Dynamic Routing?

Dynamic routing lets you define routes that include variables or parameters. These parameters are placeholders in the route path, which React Router can capture and use to load specific content for each route. Dynamic routes are especially useful for building applications that involve:

  • User profiles (e.g., /profile/:userId)
  • Product pages (e.g., /product/:productId)
  • Blog posts (e.g., /post/:postId)

Dynamic Route Syntax

To create a dynamic route, use a colon (:) followed by a parameter name in the path attribute of a <Route /> component. For example:

<Route path="/profile/:userId" element={<UserProfile />} />

In this example, :userId is a dynamic parameter that changes based on the user’s ID in the URL.


Setting Up Dynamic Routes

Let’s start by setting up a basic dynamic route in a React application.

Example: Defining a Dynamic Route

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import UserProfile from './components/UserProfile';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/profile/:userId" element={<UserProfile />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

In this example:

  • We define a dynamic route /profile/:userId in the App component.
  • When a user navigates to a URL like /profile/123, React Router renders the UserProfile component and assigns 123 as the value of the userId parameter.

Accessing Route Parameters with useParams

To retrieve dynamic route parameters in a component, use the useParams hook from React Router. The useParams hook returns an object containing all the parameters defined in the route.

Example: Accessing Route Parameters with useParams

import React from 'react';
import { useParams } from 'react-router-dom';

function UserProfile() {
  const { userId } = useParams();

  return (
    <div>
      <h2>User Profile</h2>
      <p>User ID: {userId}</p>
    </div>
  );
}

export default UserProfile;

In this example:

  • useParams captures the userId from the URL when navigating to /profile/:userId.
  • userId can then be used in the component to fetch user data or display personalized content.

Example 1: Dynamic Route for Product Details

Let’s create a simple product detail page with a dynamic route. Imagine you have a list of products, each with a unique ID. When a user clicks on a product, they are taken to a detailed view of that product.

Step 1: Defining the Dynamic Route

In the App component, define a route for product details:

import ProductDetail from './components/ProductDetail';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/product/:productId" element={<ProductDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

Step 2: Fetching Product Data in ProductDetail

In the ProductDetail component, use useParams to get the productId from the URL and fetch the product data.

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

function ProductDetail() {
  const { productId } = useParams();
  const [product, setProduct] = useState(null);

  useEffect(() => {
    // Simulating a fetch request
    const fetchProduct = async () => {
      const productData = await fetch(`/api/products/${productId}`).then(res => res.json());
      setProduct(productData);
    };
    
    fetchProduct();
  }, [productId]);

  if (!product) return <p>Loading...</p>;

  return (
    <div>
      <h2>{product.name}</h2>
      <p>Price: ${product.price}</p>
      <p>Description: {product.description}</p>
    </div>
  );
}

export default ProductDetail;

In this example:

  • useParams captures the productId from the URL.
  • useEffect fetches the product data based on the productId.
  • The component renders the product name, price, and description once the data is fetched.

Example 2: Blog Post Pages with Dynamic Routing

Dynamic routes are also useful for blog posts where each post has a unique identifier.

Step 1: Defining the Blog Post Route

Define a route in your App component:

import BlogPost from './components/BlogPost';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/post/:postId" element={<BlogPost />} />
      </Routes>
    </BrowserRouter>
  );
}

Step 2: Using useParams in BlogPost

The BlogPost component will retrieve the postId from the URL and use it to fetch the appropriate blog post data.

import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

function BlogPost() {
  const { postId } = useParams();
  const [post, setPost] = useState(null);

  useEffect(() => {
    const fetchPost = async () => {
      const postData = await fetch(`/api/posts/${postId}`).then(res => res.json());
      setPost(postData);
    };
    
    fetchPost();
  }, [postId]);

  if (!post) return <p>Loading...</p>;

  return (
    <div>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </div>
  );
}

export default BlogPost;

In this example:

  • postId is extracted from the URL using useParams.
  • The component then fetches the blog post based on the postId and displays its title and content.

Using Nested Dynamic Routes

In more complex applications, you may need nested dynamic routes. For instance, in an e-commerce application, you may have a main category route with a nested product route.

Example: Category and Product Nested Routes

Define nested routes with parameters:

import Category from './components/Category';
import Product from './components/Product';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/category/:categoryId" element={<Category />}>
          <Route path="product/:productId" element={<Product />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}
  • /category/:categoryId will render the Category component.
  • /category/:categoryId/product/:productId will render the Product component nested within Category.

Using useNavigate for Programmatic Navigation

If you want to navigate programmatically based on certain conditions (e.g., after form submission or button click), you can use the useNavigate hook.

Example: Programmatic Navigation with useNavigate

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

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

  const goToProduct = (productId) => {
    navigate(`/product/${productId}`);
  };

  return (
    <div>
      <button onClick={() => goToProduct(123)}>Go to Product 123</button>
    </div>
  );
}

In this example:

  • useNavigate provides a function to navigate to a dynamic route (/product/:productId).
  • Clicking the button will navigate to the specified product page.

Tips for Using Dynamic Routes

  1. Parameter Naming: Use descriptive names for parameters to make code easier to understand.
  2. Error Handling: Include error handling to display a message if the data doesn’t load successfully.
  3. Performance Optimization: If fetching data for each route, use React’s state and effects to optimize performance and minimize unnecessary re-renders.

Conclusion

In this lesson, we covered:

  • How to create dynamic routes in React Router
  • How to access route parameters using useParams
  • Examples of dynamic routing for product pages, blog posts, and nested routes

Dynamic routing is a powerful tool for making your application more flexible and personalized. In the next lesson, we’ll dive into Route Parameters to explore how to work with multiple parameters in your routes.