Hello! Welcome to the next lesson on our journey with React Router.
In our previous lessons, we've successfully set up static routes and built a navigation bar using <Link> and <NavLink>, allowing users to move between pages like Home, Products, and About. Our application can display a list of all products, but it's not yet capable of showing a detailed page for a single, specific product.
Today, we'll tackle exactly that. We're going to learn how to create dynamic routes. These are routes that include a variable segment in the URL, like /products/1 or /products/computer-keyboard. This will allow us to create a unique page for every product in our catalog.
As a Laravel developer, you're already familiar with this concept. In Laravel, you'd define a route like Route::get('/products/{id}', ...). We're going to implement the client-side equivalent using React Router. The goal is to define the route pattern and create the links that point to these new, dynamic pages.
1. Understanding Dynamic Route Segments
A dynamic route segment is a part of the URL path that acts as a placeholder. React Router uses a colon (:) prefix to denote a dynamic segment.
For example, in the route path /products/:productId, the :productId part is dynamic. It will match URLs like:
/products/1/products/42/products/dell-xps-laptop
The value that replaces :productId (e.g., 1, 42, or dell-xps-laptop) is a URL parameter. We'll learn how to access this parameter in the next lesson. For today, our focus is on setting up the route and linking to it.
To see how this is done, let's look at a guide that walks through this process.
React Router v6: A Beginner's Guide - SitePoint
The following article, "React Router v6: A Beginner's Guide", provides excellent examples of creating dynamic routes. We'll focus on the sections that demonstrate setting up the route path and linking to it.
Please read the section titled Nested Routing with Path Parameters. Focus on the code for the Products.js component. Pay attention to two key things: How the <Route path=":productId" ... /> is defined. How the linkList constant is created by mapping over productData to generate <Link> components with dynamic to props.
2. Implementing Our Dynamic Product Route
Let's apply what you've just read to our project. We'll create a simple product data array and then set up the necessary routes and links.
Step 1: Create Mock Product Data
First, we need some data to work with. Create a new file in your src directory called data.js.
// src/data.js
export const productData = [
{
id: 1,
name: "Classic Leather Wallet",
description: "A timeless and durable wallet made from genuine leather.",
status: "Available",
},
{
id: 2,
name: "Modern Smartwatch",
description: "Stay connected with this sleek and feature-packed smartwatch.",
status: "Available",
},
{
id: 3,
name: "Wireless Bluetooth Headphones",
description: "Experience immersive sound with these comfortable, noise-cancelling headphones.",
status: "Out of Stock",
},
];
Step 2: Link to Individual Product Pages
Now, let's modify our ProductsPage to display a list of links, where each link points to a specific product's future detail page.
Update your src/pages/ProductsPage.jsx:
// src/pages/ProductsPage.jsx
import React from 'react';
import { Link } from 'react-router-dom';
import { productData } from '../data'; // Import our mock data
const ProductsPage = () => {
return (
<div>
<h1>Our Products</h1>
<p>Browse our selection of high-quality products.</p>
<ul>
{productData.map(product => (
<li key={product.id}>
<Link to={`/products/${product.id}`}>
{product.name}
</Link>
</li>
))}
</ul>
</div>
);
};
export default ProductsPage;
Notice the to prop on the <Link> component: to={\/products/${product.id}`}. We're using a template literal to dynamically construct the URL for each product based on its id. When you click on "Classic Leather Wallet", the browser URL will change to /products/1`.
Step 3: Define the Dynamic Route
The links now point to the correct URLs, but React Router doesn't know what component to render for /products/1. Let's fix that.
First, create a placeholder component for the product detail page.
Create src/pages/ProductDetailPage.jsx:
// src/pages/ProductDetailPage.jsx
import React from 'react';
const ProductDetailPage = () => {
return (
<div>
<h2>Product Detail Page</h2>
<p>Details for a specific product will be shown here.</p>
</div>
);
};
export default ProductDetailPage;
Now, let's add the dynamic route to our main router setup in App.jsx.
Update src/App.jsx:
// src/App.jsx
import React from 'react';
import { Routes, Route } from 'react-router-dom';
// Import your page components
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import ProductsPage from './pages/ProductsPage';
import ProductDetailPage from './pages/ProductDetailPage'; // Import the new component
import NotFoundPage from './pages/NotFoundPage';
import Navbar from './components/Navbar';
function App() {
return (
<div>
<Navbar />
<main>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/products" element={<ProductsPage />} />
{/* Add the new dynamic route below */}
<Route path="/products/:productId" element={<ProductDetailPage />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</main>
</div>
);
}
export default App;
The key addition is <Route path="/products/:productId" element={<ProductDetailPage />} />. This tells React Router: "whenever the URL matches the pattern /products/ followed by some value, render the ProductDetailPage component". The :productId part is the placeholder for our dynamic ID.
Now, run your application. Navigate to the /products page. You should see a list of your products. Clicking on any of them will change the URL (e.g., to /products/2) and display the "Product Detail Page" placeholder content.
Conclusion
Great work! You have successfully laid the foundation for displaying detailed product pages. You now understand how to create dynamic route patterns and generate links that navigate to them.
Key Takeaways:
- Dynamic routes use a colon (
:) to define a URL parameter (e.g.,:productId). - The
<Route path="/products/:productId" ... />definition catches all URLs that fit the pattern. - You can create links to dynamic routes using template literals within the
<Link>component'stoprop:to={\/products/${id}`}`.
Right now, our ProductDetailPage is just a static placeholder. It always shows the same content regardless of whether the URL is /products/1 or /products/2.
Preview of the Next Lesson:
In our next lesson, we will bring the ProductDetailPage to life. We will learn how to use the useParams hook to access the productId from the URL within our component. This will allow us to find the correct product in our data and display its specific details, making the page truly dynamic.