Topic 38 of 54
Dynamic Routes & useParams
Overview
If you have an e-commerce store with 10,000 products, you don't write 10,000 `<Route>` components. You write one 'Dynamic Route'. A dynamic segment of a URL acts as a variable placeholder (like `/product/123`). The component that loads can then read that variable (`123`) from the URL to know which specific product's data it should fetch from the database.
Syntax
This single route will successfully match `/product/1`, `/product/apple`, and `/product/999`.
Defining a Dynamic Route
jsx
// App.jsx
import { Routes, Route } from 'react-router-dom';
import ProductDetails from './ProductDetails';
function App() {
return (
<Routes>
{/* The colon ':' tells React Router this is a dynamic variable named 'productId' */}
<Route path="/product/:productId" element={<ProductDetails />} />
</Routes>
);
}`useParams` returns an object containing all the dynamic segments of the current URL.
Reading the Parameter with useParams
jsx
// ProductDetails.jsx
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
function ProductDetails() {
// Destructure the variable name we defined in the Route path
const { productId } = useParams();
const [product, setProduct] = useState(null);
useEffect(() => {
// We use the ID from the URL to fetch the correct data
fetch(`/api/products/${productId}`)
.then(res => res.json())
.then(data => setProduct(data));
}, [productId]); // Re-fetch if the URL parameter changes!
if (!product) return <p>Loading...</p>;
return <h1>{product.name}</h1>;
}Common Pitfalls
- Forgetting to include the parameter in the `useEffect` dependency array. If the user clicks a link to go from `/product/1` to `/product/2`, the component doesn't unmount; it just re-renders. If `productId` isn't in the array, the fetch won't trigger, and they'll still see product 1's data!
Interview Tips
- Remember that parameters extracted from `useParams` are always Strings. If your database requires an Integer, you must parse it: `parseInt(productId, 10)`.
Real-World Example
Multiple dynamic parameters in a single route.
example
jsx
// Route: <Route path="/users/:userId/orders/:orderId" element={<Order />} />
function Order() {
const { userId, orderId } = useParams();
return (
<p>Viewing Order #{orderId} for User #{userId}</p>
);
}