Home / Blog /
React Router: How to implement routing in React
//

React Router: How to implement routing in React

//
Tabnine Team /
6 minutes /
April 25, 2021

Routing is a necessity when it comes to JavaScript-based single-page applications (SPAs). At some point, your app is going to need navigation. The way SPAs work is by sending the compiled and minified JavaScript file over with the HTML and CSS, then proceeds to render the site with lazy loading techniques to provide the user with a just-in-time browsing experience.

Routing is the technique that gives the impression of the app or website multiple pages or views. However, in reality, it’s all still just the same original page sent from the server-side. All the processing is completed on the client-side in a seamless manner.

So how does routing and redirecting work in React?

Unlike Angular and other JavaScript-based SPA frameworks, React doesn’t come with a pre-built routing system. React, after all, just a UI library. This means that its sole purpose is to help developers organize and render UI in the most effective and efficient manner. Routing is considered an extra feature.

However, the perks of React is that it has a strong developer community, meaning that common development needs — such as routing — have already been addressed via an add-on library to React.

In our case, it’s called React Router.

Routing in React: Installation

There are two ways you can install React Router into your React project. The first method is to add it to your project repository via yarn.

 yarn add react-router-dom

Alternatively, you can do so using npm install

 npm install react-router-dom

Debugging notes:

You might run into a potential conflict with babel jest when you try to use React Router. It’s similar to the issue that occurs when you install node-sass. You’ll see the conflict pop up in your console when you try to start your React application.

When this happens, it’s because the dependencies of babel jest are different from the react-router library we’ve just installed. If you look at the actual error, most of the time, it’s not the major versions that are in conflict with one another — rather, it’s the minor trailing updated versions.

To fix this, go inside your packages.json and add a resolutions property and tell it that we always want babel jest to be a specific version no matter what.

Here is an example of what this might look like:

 ...
 "devDependencies":{
  "react-scripts": "3.0.0"
 },
 "resolutions":{
  "babel-jest":"24.7.1"
 }
 ...

After you’ve done this, save your file and reinstall your React Router library. Once this is completed, you should have no problem starting your application.

Using React Router

Before you can begin to use routing in your React app, you need to go to your index.js and import in BrowserRouter.

It looks something like this:

 import React from 'react';
 import ReactDOM from 'react-dom';
 import { BrowserRouter } from 'react-router-dom';

BrowserRouter is actually a component that you can use to wrap around your application to make routing possible. What this does is give your <App /> component all the functionality available within BrowserRouter.

Here is how it looks in the code:

 ...
 ​
 ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
 );
 ​
 ...

So how do you use it in an actual component? Let’s do an example route inside your App.js.

Start by importing Route into your component.

 ...
 import { Route } from 'react-router-dom';
 ​
 ...

Now we’re going to make a quick component that renders out a <div>.

 const catsPage = () => (
  <div>
    <h1>CATS!</h1>
  </div>
 )

This component is going to represent  another page that’s alternate to our base rendered homepage. Here’s the code for that part.

 function App() {
    return (
      <div>
        <HomePage />
      </div>
    )
 }

Note: We’re going to pretend that your <HomePage /> lives in another file and pulled into this file via import.

The route component works by taking a few arguments. The main ones for this tutorial that we’re going to focus on are exact, path, and component.

Here’s a breakdown of what they do:

component: component is what we want the route to render.

path: the string that we want our string to equal to based on where we currently are. For example, if our component={HomePage}, then we might want our path to be path='/', which is the base of our application.

exact: this is a true or false boolean property. If you don’t assign anything to it, then it will default to true. exact tells the app that the path must be exactly what you set it as in order for the assigned component to render.

Here is what it looks like in the React code if we swap out <HomePage /> as per the code block example above:

 function App() {
    return (
      <div>
        <Route exact path='/' component={HomePage} />
      </div>
    )
 }

In the example above, if you had something like localhost:3000/, then it will render the HomePage component as expected.

But what happens if you remove  exact from Route? You might have a link like localhost:3000/random and React Router library will still evaluate that as true and end up showing the HomePage component.

Now, this is where the fun part begins. If we created another route in React without using exact, what will happen is that React will render whatever comes up as true.

Let’s take a look at the follow block of example code:

 function App() {
    return (
      <div>
        <Route path='/' component={HomePage} />
        <Route path='/cats' component={CatsPage} />
      </div>
    )
 }

Without exact, the link localhost:3000/cats will evaluate  HomePage to true and render it, followed by CatsPage directly beneath it. Without exact in React Router, as long as the path matches (even if it’s just a partial match), it will evaluate to true and render.

However, if you throw in exact, then it will have to be exactly as-is stated. So, for example, if you throw exact back into the route for HomePage, it won’t render when you try localhost:3000/cats because it’s not an exact match.

Switch Component in React Router

To use the Switch component, we need to add it to the import like so:

 ...
 ​
 import { Route, Switch } from 'react-router-dom';
 ​
 ...

And then wrap your <Route /> components within <Switch> like this:

 function App() {
    return (
      <div>
        <Switch>
          <Route path='/' component={HomePage} />
          <Route path='/cats' component={CatsPage} />
        </Switch>
      </div>
    )
 }

What <Switch> does is that when a route inside the <Switch> tag pair finds a match in the path,  it does not render anything else but that route. So, before, when we didn’t have exact as a property inside our <Route />, localhost:3000/cats will render both HomePage and CatsPage.

However, if we use <Switch>, it will match / first and not render anything else that may also evaluate to true. This means that if we tried to go to localhost:3000/cats, only our HomePage will show up.

So when we put exact back into <Route exact path='/' component={HomePage} />, then it will only render CatsPage. In short, you can think of <Switch> as a first match route rendering tool. <Switch> comes in handy when we don’t want to accidentally render multiple components that may have matching paths.

With the combination of <Route> and <Switch>, this is conceptually what routing is in React.

How to dynamically route in React

When <Route> renders a component for us, the component itself also gets passed three arguments. So, for example, <Route path='/' component={HomePage} /> will have the following arguments in the props — history, location, and match. For this section, we’re going to focus on match.

Inside our match, we get four things and they are url, path, params, and isExact. The url is the url of the component that it got rendered up to from the route. In our previous examples, we know that any path without exact will be partially matched. The url inside match tells us what portion of the url we’ve put into the browser is the valid part that evaluated it to true. The path inside match is just telling us the pattern that the url is trying to match.

The isExact is only true if the url matches the entire path pattern. Where does this come in handy?

When we use <Route /> without exact, it will render anything that matches. This means, for our HomePage and CatsPage example, if we had localhost:3000/cats without using exact, isExact under HomePage will display as false while CatsPage will return true. This gives us granularity in the future to use for whatever we might need to.

Finally, the params property is an object of url parameters. What is a url parameter? Here is an example:

 <Route path='/cats/:catName' component={CatPage} />

The url parameter in the code above is :catName. :catName represents a dynamically changing value that can be anything we want it to be. This property is also accessible as a parameter via the params property under match.

So if we wanted to use this parameter, we can do so via props in our React code.

Here is an example:

 const CatPage = props => {
  return(
  <div>
  <h1>Hello, my name is {props.match.params.catName}</h1>
  </div>
  );
 };

Other spaces you might use params is when you want to fetch some data relating to the page, you have the details necessary to fetch through API calls to your backend.

And that’s basically it for React Routing and redirecting in React in a nutshell. The explanations and examples here here should be enough to get you started on creating your own routes in React quickly and efficiently.