Route Parameters
Route parameters represent dynamic parts of a URL.
They let one route handle many specific resources.
<Route path="/products/:productId" element={<ProductDetailsPage />} />This route matches:
/products/1/products/keyboard/products/abc-123
Reading Params
Use useParams.
import { useParams } from "react-router-dom";
function ProductDetailsPage() {
const { productId } = useParams();
return <h1>Product {productId}</h1>;
}Route params are strings.
If you need a number, convert and validate it.
const productIdNumber = Number(productId);
if (!Number.isInteger(productIdNumber)) {
return <p>Invalid product ID.</p>;
}Multiple Params
<Route path="/teams/:teamId/projects/:projectId" element={<ProjectPage />} />function ProjectPage() {
const { teamId, projectId } = useParams();
return (
<p>
Team: {teamId}, project: {projectId}
</p>
);
}Use clear parameter names.
Params vs Query Strings
Use path params for identity.
/products/42
/users/ava
/teams/t1/projects/p9Use query strings for optional view state.
/products?category=books&page=2
/search?q=reactIf removing the value means you no longer know which resource to show, it probably belongs in the path.
If removing the value still leaves a valid page with default state, it may belong in the query string.
Fetching with Params
function ProductDetailsPage() {
const { productId } = useParams();
const [product, setProduct] = useState(null);
useEffect(() => {
let ignore = false;
fetch(`/api/products/${productId}`)
.then((response) => response.json())
.then((data) => {
if (!ignore) {
setProduct(data);
}
});
return () => {
ignore = true;
};
}, [productId]);
if (!product) {
return <p>Loading...</p>;
}
return <h1>{product.name}</h1>;
}Include the param in dependencies so the effect runs when the route changes.
Optional and Catch-All Routes
React Router supports patterns for splat routes with *.
<Route path="/docs/*" element={<DocsPage />} />Use catch-all routes carefully. They can hide route design problems if everything is matched too broadly.
Common Mistakes
- Forgetting that params are strings.
- Not handling invalid or missing resources.
- Leaving route params out of effect dependencies.
- Using query strings for required resource identity.
- Using vague param names like
:idin deeply nested routes where:projectIdwould be clearer.
Which URL value is best represented as a route parameter?
Recap
Route params make URLs dynamic.
Read them with useParams, validate them as needed, and choose between path params and query strings based on whether the value identifies the page or configures the view.
Practice
Create routes for /users/:userId and /teams/:teamId/users/:userId.
Read the params, validate that IDs are present, and show a friendly message when the resource cannot be found.