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 theApp
component. - When a user navigates to a URL like
/profile/123
, React Router renders theUserProfile
component and assigns123
as the value of theuserId
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 theuserId
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 theproductId
from the URL.useEffect
fetches 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:
postId
is extracted from the URL usinguseParams
.- 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 theCategory
component./category/:categoryId/product/:productId
will render theProduct
component 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:
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
- 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.