How To Use URL Parameters In React Router

React

18/06/2019


When it comes to routing in any type of application, you will always come across two types: static and dynamic routing. Static routes are what most people are familiar with when they start out. These are predetermined routes such as /home or /about/history. On the other hand, your dynamic routes are determined as your app is rendering. This provides a number of advantages over static routing, which I will get into later on. Moreover, this tutorial will be specifically focusing on responsive routing, that is, how to use URL parameters in React Router.

New to React Router and need an introduction instead? Check out my article here to get started!

URL parameters explained

So what are URL or route parameters exactly? Well, let's imagine you are selling products on your website and each product has its own product page. How would go about programming this? Hard-code a product page for each product? Well, maybe if you have 1 or 2, but imagine you have 100 or more... that might not be the best idea. 😰

Rather, you should keep things DRY (Don't Repeat Yourself) and create a single product page that changes its displayed information depending on which product a user is currently looking at. And how would we do this? Well, with the use dynamic routing, i.e. responsive routing!

Dynamic routing tutorial is about dynamic routing. Who would have thought?

Responsive routing let's us use variables in our routes that can take on any kind string value. In our responsive route, we distinguish a route parameter or variable by placing : in front of it. For instance, the dynamic route /product/:id can now take the values /product/1 or /product/laptop_4. From these routes, we could then extract the product ID, retrieve any data related to that id from a database and consequently display it on our page.

On a side note: the end of a route parameter can be marked by a /. Thus, id would be valid parameter in /product/:id/price

Setting up responsive routes

Alright, it's time to code ladies and gents! 👩‍💻Below we have a small example of 2 routes with corresponding components. Nothing fancy here...

JSX
import React from 'react';
import { Route, NavLink } from 'react-router-dom';
function Product() {
return (
<div>This is our lovely product page!</div>
);
}
function HomePage() {
return (
<div>Welcome to Chunk Bytes!</div>
);
}
function App() {
return (
<div className="App">
<header>
<nav>
<ul>
<li><NavLink to="/">Home</NavLink></li>
<li><NavLink to="/product">Product</NavLink></li>
</ul>
</nav>
</header>
<div>
<Route exact path="/" component={HomePage} />
<Route path="/product" component={Product} />
</div>
</div>
);
}
export default App;

Let's make our product page a bit more dynamic with the following changes. First, let's add a parameter to our product route with path="/product/:id". Next, let's create two NavLinks, each pointing to two different products.

JSX
// Removing the regular product page
<li><NavLink to="/product">Product</NavLink></li>
// Adding two new NavLinks
<li><NavLink to="/product/laptop1">Laptop</NavLink></li>
<li><NavLink to="/product/car1">Car</NavLink></li>

With these simple steps, we already created a responsive route. Hooray! 😋 But of course, we're not done yet! 😤 Next, we need to extract our product IDs from the route, so our Product component knows which product information to retrieve and render. So how do we retrieve this information?

Retrieving URL parameter information

We all know that React components automatically receive a props parameter (I hope you do... 😳). This is also where we can find our route parameter value. Let's console.log our component's props and see what it has to offer.

Console Output Of Component Props

Console Output Of Component Props

As we can see, props has several properties. However, there's one in particular that is of interest to us: match. This in turn has another property called params that actually contains the value we are looking for. Alright! So let's make some final changes to our code before we wrap things up.

JSX
function Product({ match }) {
return (
<div>
This is our lovely product page!
You are currently viewing {match.params.id}
</div>
);
}

Instead accessing our route parameter value with props.match.params.id, we can do some destructuring with { match }. You could even destructure a layer deeper to keep things simpler, e.g. { match: { params }}. Destructur-...ception? 🤨

A teeny-tiny gotcha

If you're rendering your component in a route using the render props, e.g. <Route path="/product/:id" render={() => <Product />} />, make sure to actually pass the props into your component as follows: render={(props) => <Product {...props} />} />. I've done this mistake myself 😬 and I've seen many others do it. If you don't, you will see errors such as TypeError: match.params.id is undefined.


WRITTEN BY

Code and stuff