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/:userIdin theAppcomponent. - When a user navigates to a URL like
/profile/123, React Router renders theUserProfilecomponent and assigns123as the value of theuserIdparameter.
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:
useParamscaptures theuserIdfrom the URL when navigating to/profile/:userId.userIdcan 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:
useParamscaptures theproductIdfrom the URL.useEffectfetches the product data based on theproductId.- 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:
postIdis extracted from the URL usinguseParams.- The component then fetches the blog post based on the
postIdand 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/:categoryIdwill render theCategorycomponent./category/:categoryId/product/:productIdwill render theProductcomponent nested withinCategory.
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:
useNavigateprovides 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
- Parameter Naming: Use descriptive names for parameters to make code easier to understand.
- Error Handling: Include error handling to display a message if the data doesn’t load successfully.
- 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.
