Routing In React Js | Using react-router-dom

Routing In React Js | Using react-router-dom

What is Routing?

Routing is capability of web application to load different component/pages whenever a link is clicked. Now you will be thinking about how it is different from anchor tag <a />. yah you are correct when we talk in a general sense both are the same but when we talk about React it’s different. In React, our web application will have one root url/address which will give expose all pages/functionality for our app. But when our react web application has routing enabled then different functionality can have different url.

Example: Every website use to have home, contact us and about us component. So when we implement routing in react then each of these component can have separate individual urls like /about-us, /home, /contact-us.

How to implement Routing in React

To implement routing in react we have to add a react module called react-router-dom to our application. To add this we have to execute below command from the root of the project.

npm install react-routing-dom

Let’s create a project using below command

create-react-app routing

Now we will add routing module using command

npm install react-routing-dom

This command will add two module in our react app under node_modules

  1. react-router module: This is the core module for react routing.
  2. react-router-dom module: This module is bootstrap on top of react-router and enables routing for web applications.

How our project structure will look like.

React Routing Project Structure
React Routing Project Structure

Here we have component folder under src which will hold all our react components.

In this project we have included bootstrap for styling. If you want to add you can check this post.

Creating Home, About Us And Contact us components

Home Component

We create file under component folder named home.jsx

import React, { Component } from "react";

class HomeComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  style = {
    textAlign: "center",
  };
  render() {
    return (
      <div>
        <div class="row">
          <div class="col col-sm-12 mx-auto" style={this.style}>
            <h1>Home</h1>
          </div>
          <div class="col col-sm-12">
            <p>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras
              finibus consectetur lorem, a pellentesque lorem commodo id. Nullam
              non lacinia ligula. Lorem ipsum dolor sit amet, consectetur
              adipiscing elit. Mauris euismod justo vitae erat lobortis
              fermentum. Etiam volutpat leo vel erat commodo, auctor varius nisi
              rutrum. In non mollis erat, vel sagittis velit. Nunc porta
              venenatis erat, quis fermentum eros tincidunt quis. Duis id
              tincidunt enim. Sed eros velit.
            </p>
          </div>
        </div>
      </div>
    );
  }
}

export default HomeComponent;

About US Component

create file aboutus.jsx under folder component.

import React, { Component } from "react";

class AboutUsComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  style = {
    textAlign: "center",
  };
  render() {
    return (
      <div>
        <div class="row">
          <div class="col col-sm-12" style={this.style}>
            <h1>About Us</h1>
          </div>
          <div class="col col-sm-12">
            <p>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras
              finibus consectetur lorem.
            </p>
          </div>
        </div>
      </div>
    );
  }
}

export default AboutUsComponent;

Contact Us Component

import React, { Component } from "react";

class ContactUsComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  style = {
    textAlign: "center",
  };
  render() {
    return (
      <div>
        <div class="row">
          <div class="col col-sm-12 mx-auto" style={this.style}>
            <h1>Contact Us</h1>
          </div>
          <div class="col col-sm-12">
            <p>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam
              feugiat nisi fringilla tellus interdum posuere. Etiam faucibus
              velit a ex condimentum, sed viverra lorem aliquet. In sed leo quis
              ex tincidunt consequat. Morbi sed ipsum et metus euismod
              sollicitudin id eget justo. Maecenas tristique tellus id ligula
              venenatis rhoncus. In quis diam malesuada, egestas sem eget,
              sagittis est. Aenean scelerisque urna quis pellentesque molestie.
            </p>
          </div>
        </div>
      </div>
    );
  }
}

export default ContactUsComponent;

Adding Routers in App Components

Now, lets add App Component under src folder of file name app.js .

import React from "react";
import HomeComponent from "./component/home";
import NavbarComponent from "./component/navbar";
import AboutUsComponent from "./component/aboutus";
import ContactUsComponent from "./component/contactus";
import { Route, BrowserRouter as Router, Link } from "react-router-dom";

function App() {
  const routing = (
    <Router>
      <NavbarComponent />
      <div>
        <Route exact path="/" component={HomeComponent} />
        <Route path="/home" component={HomeComponent} />
        <Route path="/about-us" component={AboutUsComponent} />
        <Route path="/contact-us" component={ContactUsComponent} />
      </div>
    </Router>
  );
  return (
    <div>
      <div className="container">
        <div className="row">
          <div className="col col-sm-12">{routing}</div>
        </div>
      </div>
    </div>
  );
}

export default App;

In above code focus on line 9-18 here we are using Router and Route .

Router

React Router package includes number of ways like BrowserRouter and HashRouter to include routing depending on platform for which you are developing react application. Here in this post we are developing react web application that will be used in a browser that’s why we are using BrowserRouter . This you can clearly see in imports at line no 6 in above code.

import { Route, BrowserRouter as Router, Link } from "react-router-dom";

Here we are using BrowserRouter as Router. Router is alias for BrowserRouter.

BrowserRouter component will enclose Route and Link.

<Router>
      <Link to="/home" />
      <Link to="/about-us" />
      <Link to="/contact-us" />
      <div>
        <Route exact path="/" component={HomeComponent} />
        <Route path="/home" component={HomeComponent} />
        <Route path="/about-us" component={AboutUsComponent} />
        <Route path="/contact-us" component={ContactUsComponent} />
      </div>
    </Router>

Route

Route is very important element in routing. Route maps component to specific path. Route attribute path will define the url path at which component, defined by component attribute becomes active.

Link

Link work similar to anchor tag that works in HTML. but Link's to attribute can hold only path for components or react elements.

In our app.js we saw navbar.jsx instead of Link this is because navbar.jsx hold all the Link as shown in below code.

Navbar Component

navbar.jsx

import React, { Component } from "react";
import { Link } from "react-router-dom";

class NavbarComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <React.Fragment>
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
          <a class="navbar-brand">
            <Link to="/home">Routing Example</Link>
          </a>
          <ul class="navbar-nav mr-auto mt-2 mt-lg-0">
            <li class="nav-item">
              <a class="nav-link">
                <Link to="/home">Home</Link>
                {/* <span class="sr-only">(current)</span> */}
              </a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">
                <Link to="about-us">About Us</Link>
              </a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">
                <Link to="/contact-us">Contact Us</Link>
              </a>
            </li>
          </ul>
        </nav>
      </React.Fragment>
    );
  }
}

export default NavbarComponent;

What we achieved till now.

After completing this post till here you have created 3 component home, contact us and about us. And also one app component with navbar component that will help you to route through home, aboutus, and contact us components. Some thing like shown below

Basic of Routing in react

Adding 404 page in React

In above post we added home, contact us and about us route but what if some one request the url that is not available in router. Then that case we have to display proper 404 message. Let’s achieve this functionality by creating component PageNotFoundComponent.

create 404.jsx file under component folder and add the below code

import React, { Component } from "react";

class PageNotFoundComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  style = {
    textAlign: "center",
  };
  render() {
    return (
      <React.Fragment>
        <div class="container" style={this.style}>
          <div class="row">
            <div class="col-md-12">
              <div class="error-template">
                <h1>Oops!</h1>
                <h2>404 Not Found</h2>
                <div class="error-details">
                  Sorry, an error has occured, Requested page not found!
                </div>
              </div>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

export default PageNotFoundComponent;

Now, after creating PageNotFoundComponent lets have the entry in App.js that will be responsible for routing all unknown request PageNotFoundComponent.

App.js

import React from "react";
import HomeComponent from "./component/home";
import NavbarComponent from "./component/navbar";
import AboutUsComponent from "./component/aboutus";
import ContactUsComponent from "./component/contactus";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import PageNotFoundComponent from "./component/404";

function App() {
  const routing = (
    <Router>
      <NavbarComponent />
      <div>
        <Route exact path="/" component={HomeComponent} />
        <Route path="/home" component={HomeComponent} />
        <Route path="/about-us" component={AboutUsComponent} />
        <Route path="/contact-us" component={ContactUsComponent} />

        <Route path="*" component={PageNotFoundComponent} />
      </div>
    </Router>
...

You can find in above code, that we added Route with path as * and component as PageNotFoundComponent. This * make sure that all invalid requests will be served with PageNotFoundComponent.

Example: If we give localhost:3000/invalidurl will give us below result

404 page not found error page
404 page not found error page in react

Note: What if you move Route with PageNotFoundComponent to top as shown below

          <Route path="*" component={PageNotFoundComponent} />

          <Route exact path="/" component={HomeComponent} />
          <Route path="/home" component={HomeComponent} />
          <Route path="/about-us" component={AboutUsComponent} />
          <Route path="/contact-us" component={ContactUsComponent} />

Then all pages will give serve PageNotFoundComponent even for valid request. Here about-us will also serve us PageNotFoundComponent.

PageNotFoundComponent served for all URL
PageNotFoundComponent served for all URL

So, this route should be present at the last.

Here is one more catch. When you visit to /home or /about-us or any valid urls also you will see 404 component displayed below of actual content as shown.

To, resolve this we can make a use of React-Router Switch component.

Using React-Router-Dom’s Switch

Switch: React-Router package contains Switch Component which encloses multiple Routes. This Switch component makes sure that only the first match of the path is loaded.

Let’s update App.js with Switch.

App.js

import React from "react";
import HomeComponent from "./component/home";
import NavbarComponent from "./component/navbar";
import AboutUsComponent from "./component/aboutus";
import ContactUsComponent from "./component/contactus";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import PageNotFoundComponent from "./component/404";

function App() {
  const routing = (
    <Router>
      <NavbarComponent />
      <div>
        <Switch>
          <Route exact path="/" component={HomeComponent} />
          <Route path="/home" component={HomeComponent} />
          <Route path="/about-us" component={AboutUsComponent} />
          <Route path="/contact-us" component={ContactUsComponent} />

          <Route path="*" component={PageNotFoundComponent} />
        </Switch>
      </div>
    </Router>
...

Now, after adding switch only first match will be loaded means when we request /home then only home component will be loaded and not the PageNotFoundComponent as after matching the first match it will break the loading.

Adding Redirect to React Router

As we saw / and /home points to same HomeComponent why not to redirect / request to /home. Lets achieve this by adding Redirect Component for /

import React from "react";
...
function App() {
  const routing = (
    <Router>
      <NavbarComponent />
      <div>
        <Switch>
          <Route exact path="/">
            <Redirect to="/home" />
          </Route>
          <Route path="/home" component={HomeComponent} />
          <Route path="/about-us" component={AboutUsComponent} />
...

Redirect component under the Route will redirect all request coming to / to path specified in to attribute of Redirect.

Durgesh Kumar

He is the Founder of TechiJournal.com. And have 4+ years of experience as full-stack Java developer. He worked with many reputed product companies and would like to share his experience and knowledge through this blog. He works very hard to provide you with quality content. But as no one is perfect, If you feel that some improvement can be made then feel free to add it in the comment section. We look forward to it.

Leave a Reply