Understanding and implementing useParams in React Routing
I recently interacted with the usePrams
hook in a web application I was working on. I had seen it on a react routing tutorial by NetNinja UK and decided to use it on the web application I was working on. I used the useParams
hook to display individual career details on the career section of the web application.
I find it a very useful React Router hook in that it enables you to give details about individual items in a given list, for example in the case of listing products or services offered by a company or any other business. This article is a summary of my interaction with the useParams
hook and how I employed it on this particular project, let's dive right into it!
What is useParams
?
React Router is a powerful tool for creating single-page applications with dynamic, client-side routing. One of its most useful hooks is useParams
, which allows you to access dynamic parameters in the URL.
useParams
is a hook provided by React Router that enables you to extract parameters from the current URL. In other words, it allows you to have access to dynamic parameters in the URL(Uniform Resource Locator).
This is particularly useful for building dynamic and interactive web applications where components need to respond to changes in the URL.
How to use use useParams
Set up React Router
Before using useParams
, you'll need to set up React Router in your application. This typically involves installing the package and configuring your routes.
Install react-router-dom :
npm install react-router-dom
For my project, I used version 6.4 of react-router-dom
:
npm install react-router-dom@6.4
After installing react-router-dom
we then go ahead to import createBrowserRouter
,Route
, createRoutesFromElements
and RouterProvider
from react-router-dom
on the App.jsx
file for configuring the routes to various parts of the web application, for example, the Career section in my case : http://localhost:5173/careers
import {
createBrowserRouter,
Route,
createRoutesFromElements,
RouterProvider
} from 'react-router-dom'
Here is my configuration for the Careers route :
{/*careers parent route */}
<Route path='careers' element = {<CareersLayout/>} errorElement = {<CareersError />}>
<Route
index
element = {<Careers />}
loader={careersLoader}
/>
{/*career details route with parameter id */}
<Route
path = ':id'
element = {<Careerdetails/>}
loader = {careerDetailsLoader}
/>
</Route>
I have two routes defined: one for the Careers page (/careers
) and one for the Career details page (/careers/1
or /careers/2
and so on ). The :id
in path = ':id'
is a parameter that will be extracted using useParams
.
id
is an object of useParams
and must therefore match with that of the parameter name specified in the path string of the route definition(the Careers parent route configuration above) which in this case is :id
else you will encounter an error. You can name the parameter anything you want, but it is ideal to match it with one of the key in your data object so there’s no confusion.
using useParams
in a Component
I have structured my App
component by declaring an array of objects that holds the career details data. The array is on a json
file that is being hosted on a json-server.
{
"careers": [
{
"id": 1,
"title": "Senior React Developer",
"salary": 50000,
"location": "Nairobi, Kenya"
},
{
"id": 2,
"title": "Plumber",
"salary": 40000,
"location": "Mombasa"
},
{
"id": 3,
"title": "Gym Leader",
"salary": 75000,
"location": "Nakuru"
},
{
"id": 4,
"title": "Vue Developer",
"salary": 40000,
"location": "Lagos, Nigeria"
},
{
"id": 5,
"title": "Tutorial Maker",
"salary": 35000,
"location": "Kigali, Rwanda"
},
{
"id": 6,
"title": "Website Manager",
"salary": 50000,
"location": "Berlin, Germany"
},
{
"id": 7,
"title": "Food Tester",
"salary": 30000,
"location": "London, UK"
}
]
}
I employed the useParams
hook in the Careerdetails
component :
// Careerdetails.jsx
import { useLoaderData, useParams } from "react-router-dom"
export default function Careerdetails() {
// eslint-disable-next-line no-unused-vars
const { id } = useParams() //used to access the route parameter id
const career = useLoaderData()
return (
<div className='mt-4 p-8 m-12 shadow-2xl'>
<h2 className='m-2'>Career details for <span className='text-teal-700'>{career.title}</span></h2>
<p className='m-2'>Starting salary: {career.salary}</p>
<p className='m-2'>Location: {career.location}</p>
<div className='pt-4'>
<p className='text-3xl text-teal-700'>Details for the above career</p>
</div>
</div>
)
}
//career details loader: fetch details of a single career
// eslint-disable-next-line react-refresh/only-export-components
export const careerDetailsLoader = async ({ params }) => {
const { id } = params
const res = await fetch('http://localhost:4000/careers/' + id)
if (!res.ok) {
throw Error('Could not find that career')
}
return res.json()
}
In the above component (Careerdrtails.jsx
), we import useParams
from react-router-dom
and call it within the component. This returns an object containing the parameters specified in the route (in this case, just id
).
Fetching data from the json-server
:
const res = await fetch('http://localhost:4000/careers/' + id)
We then create a component that will utilize useParams
to access the id
.
The Careers.jsx
file in my case (/careers page
) :
import { useLoaderData, Link } from "react-router-dom"
export default function Careers() {
const careers = useLoaderData()
return (
<div className=''>
{careers.map(career => (
<Link className='hover:text-teal-700' to = {career.id.toString()} key={career.id}>
<div className='p-8 m-12 shadow-2xl'>
<p className=''>{career.title}</p>
<p className=''>Based in {career.location}</p>
<div>
<p>
Lorem ipsum
</p>
</div>
</div>
</Link>
))}
</div>
)
}
//careers loader function
// eslint-disable-next-line react-refresh/only-export-components
export const careersLoader = async () => {
const res = await fetch('http://localhost:4000/careers')
if (!res.ok) {
throw Error('Could not fetch the careers')
}
return res.json()
}
Link
is an element that lets the user navigate to another page by clicking on it.
Now we destructure that data to have access to it and mapping its content in a div
element with a class of Careerdetails
.
And here's how the careerdetails
page came out, on clicking the individual careers on the careers
page :
I used the useRouteError
hook to get rid of errors that may arise when one enters an invalid URL on the Careers
route.
Conclusion
useParams
is a powerful tool provided by React Router for accessing dynamic parameters from the URL. It enables the creation of dynamic and interactive web applications by allowing components to respond to changes in the URL. By following the steps outlined above, you can effectively utilize useParams
in your React applications. Happy coding!
Subscribe to my newsletter
Read articles from JOHN MURIITHI directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
JOHN MURIITHI
JOHN MURIITHI
I've been coding for three years. While being a developer is a difficult tug-of-war between my inner dreamer and critic, I've grown to love this process a lot. It hasn't just taught me much about the world, but also about myself.