Introduction

In React, routers help create and navigate between the different URLs that make up your web application. They allow your user to move between the components of your app while preserving user state, and can provide unique URLs for these components to make them more shareable. With routers, you can improve your app’s user experience by simplifying site navigation.

React Router is one of the most popular routing frameworks for React. The library is designed with intuitive components to let you build a declarative routing system for your application. This means that you can declare exactly which of your components has a certain route. With declarative routing, you can create intuitive routes that are human-readable, making it easier to manage your application architecture.

In this tutorial, you’ll install and configure React Router, build a set of routes, and connect to them using the <Link> component. You’ll also build dynamic routes that collect data from a URL that you can access in your component. Finally, you’ll use Hooks to access data and other routing information and create nested routes that live inside components that are rendered by parent routes.

By the end of this tutorial, you’ll be able to add routes to any React project and read information from your routes so that you can create flexible components that respond to URL data.

Step 1 — Installing React Router

In this step, you’ll install React Router into your base project. In this project, you are going to make a small website about marine mammals. Each mammal will need a separate component that you’ll render with the router. After installing the library, you’ll create a series of components for each mammal. By the end of this step, you’ll have a foundation for rendering different mammals based on route.

To start, install the React Router package. There are two different versions: a web version and a native version for use with React Native. You will install the web version.

In your terminal, use npm to install the package:

npm install react-router-dom

The package will install and you’ll receive a message such as this one when the installation is complete. Your message may vary slightly:

Output
...
+ react-router-dom@5.2.0
added 11 packages from 6 contributors and audited 1981 packages in 24.897s

114 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

You now have the package installed. For the remainder of this step, you’ll create a series of components that will each have a unique route.

To start, make a directory for three different mammals: manatees, narwhals, and whales. Run the following commands:

mkdir src/components/Manatee
mkdir src/components/Narwhal
mkdir src/components/Whale

Next, create a component for each animal. Add an <h2> tag for each mammal. In a full application, the child components can be as complex as you want. They can even import and render their own child components. For this tutorial, you’ll render only the <h2> tag.

Begin with the manatee component. Open Manatee.js in your text editor:

nano src/components/Manatee/Manatee.js

Then add the basic component:

router-tutorial/src/components/Manatee/Manatee.js

import React from 'react';

export default function Manatee() {
  return <h2>Manatee</h2>;
}

Save and close the file.

Next, create a component for the narwhal:

nano src/components/Narwhal/Narwhal.js

Add the same basic component, changing the <h2> to Narwhal:

router-tutorial/src/components/Narwhal/Narwhal.js

import React from 'react';

export default function Narwhal() {
  return <h2>Narwhal</h2>;
}

Save and close the file.

Finally, create a file for Whale:

nano src/components/Whale/Whale.js

Add the same basic component, changing the <h2> to Whale:

router-tutorial/src/components/Whale/Whale.js

import React from 'react';

export default function Whale() {
  return <h2>Whale</h2>;
}

Save and close the file. In the next step, you’ll start connecting routes; for now, render the basic component in your application.

Open App.js:

nano src/components/App/App.js

Add an <h1> tag with the name of the website (Marine Mammals) inside of a <div> with a className of wrapper. This will serve as a template. The wrapper and <h1> tag will render on every page. In full applications, you might add a navigation bar or a header component that you’d want on every page.

Add the following highlighted lines to the file:

router-tutorial/src/components/App/App.js

import React from 'react';
import './App.css';
function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
    </div>
  );
}

export default App;

Next, import Manatee and render inside the <div>. This will serve as a placeholder until you add more routes:

router-tutorial/src/components/App/App.js

import React from 'react';
import './App.css';

import Manatee from '../Manatee/Manatee';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <Manatee />
    </div>
  );
}

export default App;

Save and close the file.

Now that you have all of the components, add some padding to give the application a little space.

Open App.css:

nano src/components/App/App.css

Then replace the contents with the following code that adds a padding of 20px to the .wrapper class:

router-tutorial/src/components/App/App.css

.wrapper {
    padding: 20px;
}

Save and close the file. When you do, the browser will refresh to show your basic component:

Marine Mammals

Now you have a basic root component that you will use to display other components. If you didn’t have a router, you could conditionally display components using the useState Hook. But this wouldn’t offer a great experience for your users. Anytime a user refreshes the page, the user’s selection would disappear. Further, they wouldn’t be able to bookmark or share specific states of the application. A router will solve all these problems. The router will preserve the user state and will give the user a clear URL that they can save or send to others.

In this step, you installed React Router and created basic components. The components are going to be individual pages that you’ll display by route. In the next step, you’ll add routes and use the <Link> component to create performant hyperlinks.

Step 2 — Adding Routes

In this step, you’ll create a base router with individual routes for each page. You’ll order your routes to ensure that components are rendered correctly and you’ll use the <Link> component to add hyperlinks to your project that won’t trigger a page refresh.

By the end of this step, you’ll have an application with a navigation that will display your components by route.

React Router is a declarative routing framework. That means that you will configure the routes using standard React components. There are a few advantages to this approach. First, it follows the standard declaractive nature of React code. You don’t need to add a lot of code in componentDidMount methods or inside a useEffect Hook; your routes are components. Second, you can intuitively place routes inside of a component with other components serving as a template. As you read the code, you’ll find exactly where the dynamic components will fit in relation to the global views such as navigation or footers.

To start adding routes, open App.js:

nano src/components/App/App.js

The <h1> tag is going to serve as a global page title. Since you want it to appear on every page, configure the router after the tag.

Import BrowserRouter, Route, and Switch from react-router-dom. BrowserRouter will be the base configuration. Switch will wrap the dynamic routes and the Route component will configure specific routes and wrap the component that should render:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <Manatee />
    </div>
  );
}

export default App;

Add the BrowserRouter component to create a base router. Anything outside of this component will render on every page, so place it after your <h1> tag. In addition, if you have site-wide context that you want to use, or some other store such as Redux, place those components outside the router. This will make them available to all components on any route:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <BrowserRouter>
        <Manatee />
      </BrowserRouter>
    </div>
  );
}

export default App;

Next, add the Switch component inside BrowserRouter. This component will activate the correct route, much like the JavaScript switch statement. Inside of Switch, add a Route component for each route. In this case, you’ll want the following routes: /manataee, /narwhal, and /whale. The Route component will take a path as a parameter and surround a child component. The child component will display when the route is active.

Create a route for the path / and render the Manatee component:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <BrowserRouter>
        <Switch>
          <Route path="/">
            <Manatee />
          </Route>
        </Switch>
      </BrowserRouter>
    </div>
  );
}

export default App;

Save the file. When you do the browser will reload and you’ll find the information for the manatee component:

Manatee showing at route /

If you try a different route such as http://localhost:3000/whale, you’ll still find the manatee component.

Manatee on /whale route

The Switch component will render the first route that matches that pattern. Any route will match /, so it will render on every page. That also means that order is important. Since the router will exit as soon as it finds a match, always put a more specific route before a less specific route. In other words, /whale would go before / and /whale/beluga would go before /whale.

If you want the route to match only the route as written and not any child routes, you can add the exact prop. For example, <Route exact path="/manatee"> would match /manatee, but not /manatee/african.

Update the route for the Manatee component to /manatee, then import the remaining components and create a route for each:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <BrowserRouter>
        <Switch>
          <Route path="/manatee">
            <Manatee />
          </Route>
          <Route path="/narwhal">
            <Narwhal />
          </Route>
          <Route path="/whale">
            <Whale />
          </Route>
        </Switch>
      </BrowserRouter>
    </div>
  );
}

export default App;

Save the file. When you do, the browser will refresh. If you visit http://localhost:3000/, only the <h1> tag will render, because no routes match any of the Route components:

No component on /

If you visit http://localhost:3000/whale, you’ll find the Whale component:

Whale on /whale route

Now that you have some components, create navigation for a user to move between pages.

Use the <nav> element to denote that you are creating a navigation portion of the page. Then add an unordered list (<ul>) with a list item (<li>) and a hyperlink (<a>) for each mammal:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <nav>
        <ul>
          <li><a href="/manatee">Manatee</a></li>
          <li><a href="/narwhal">Narwhal</a></li>
          <li><a href="/whale">Whale</a></li>
        </ul>
      </nav>
      <BrowserRouter>
        ...
      </BrowserRouter>
    </div>
  );
}

export default App;

Save the file. When you do, the browser will refresh, but there will be a problem. Since you are using the native browser links—<a> tags—you will get the default browser behavior any time you click on a link. That means any time you click on a link, you’ll trigger a full page refresh.

Notice that the network will reload all of the JavaScript files when you click a link. That’s a big performance cost for your users.

Browser refresh on link click

At this point, you could add a click event handler on each link and prevent the default action. That would be a lot of work. Instead, React Router has a special component called Link that will handle the work for you. It will create a link tag, but prevent the default brower behavior while pushing the new location.

In App.js, import Link from react-router-dom. Then replace each <a> with a Link. You’ll also need to change the href attribute to the to prop.

Finally, move the <nav> component inside of the BrowserRouter. This ensures that the Link component is controlled by react-router:

router-tutorial/src/components/App/App.js

import React from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';
import './App.css';

import Manatee from '../Manatee/Manatee';
import Narwhal from '../Narwhal/Narwhal';
import Whale from '../Whale/Whale';

function App() {
  return (
    <div className="wrapper">
      <h1>Marine Mammals</h1>
      <BrowserRouter>
        <nav>
          <ul>
            <li><Link to="/manatee">Manatee</Link></li>
            <li><Link to="/narwhal">Narwhal</Link></li>
            <li><Link to="/whale">Whale</Link></li>
          </ul>
        </nav>
        <Switch>
          <Route path="/manatee">
            <Manatee />
          </Route>
          <Route path="/narwhal">
            <Narwhal />
          </Route>
          <Route path="/whale">
            <Whale />
          </Route>
        </Switch>
      </BrowserRouter>
    </div>
  );
}

export default App;

Save the file. When you do, the browser will refresh. When you click links, the page will not refresh and the browser will not reload the JavaScript code:

No refresh on link click

In this step you added React Router to your current project. You created a route for each component and you added a navigation using the Link component to switch between routes without a page refresh.

In the next step, you’ll add more complex routes that render different components using URL parameters.

#react #javascript #programming #web-development

How To Handle Routing in React Apps with React Router
1.80 GEEK