Route Parameters
Overview
Hardcoding every single route in a large application is impossible. If you are building Amazon, you cannot manually create 10 million routes (/products/1, /products/2, etc.) for every item in your database.
To solve this, React Router supports Dynamic Route Parameters. You define a placeholder in your route path by prefixing a word with a colon (e.g., /products/:id).
When a user visits /products/89, React Router matches the URL to the dynamic route, extracts the number 89, and exposes it to the rendered component. The component can then use the `useParams` hook to grab that ID, and use it inside a useEffect to fetch the specific details for product #89 from the backend database.
Syntax
// 1. Define the Dynamic Route with a colon (:)
<Route path="/blog/:articleSlug" element={<ArticlePage />} />
// 2. Consume it in the Component
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
function ArticlePage() {
// The variable name here MUST exactly match the name you used in the Route path
const { articleSlug } = useParams();
const [article, setArticle] = useState(null);
useEffect(() => {
// Use the dynamic parameter to fetch the specific data
fetch(`/api/articles/${articleSlug}`).then(res => setArticle(res.data));
}, [articleSlug]); // It's a dependency!
return <h1>Reading: {articleSlug}</h1>;
}Common Pitfalls
- Variable Naming Mismatch: If you define
<Route path="/user/:id" />, you MUST destructure it exactly asconst { id } = useParams(). If you try to writeconst { userId } = useParams(), it will be undefined and your API call will fail.
Interview Questions
React Router allows you to chain dynamic segments. E.g., <Route path="/teams/:teamId/players/:playerId" />. Calling useParams() will return an object containing both keys: { teamId: '...?', playerId: '...?' }.
URL Parameters (e.g., /users/123) are part of the core routing structure, typically used to identify specific resources. Query Parameters (e.g., /users?sort=asc&role=admin) are appended after a ? and are used for optional filtering, sorting, or pagination. React Router uses useSearchParams to read query parameters, not useParams.
Real-World Example
Reading Search Query Parameters: Storing UI state (like active tabs, search queries, and pagination pages) in the URL Query String is a massive best practice. It ensures that if a user copies the URL and sends it to a friend, the friend will see the exact same filtered view when the page loads.
import { useSearchParams } from 'react-router-dom';
function ProductCatalog() {
// useSearchParams behaves very similarly to useState
const [searchParams, setSearchParams] = useSearchParams();
// Read specific values from the URL: ?category=shoes&sort=price
const category = searchParams.get('category') || 'all';
const sortOrder = searchParams.get('sort') || 'popular';
const updateSort = (newSort) => {
// We update the URL query string WITHOUT deleting the existing category
setSearchParams({ category, sort: newSort });
};
return (
<div>
<p>Showing {category} sorted by {sortOrder}</p>
<button onClick={() => updateSort('price')}>Sort by Price</button>
</div>
);
}Check Your Knowledge
Test your understanding of Route Parameters with these quick questions.