Saturday, March 13, 2021

React Router

As opposed to traditional multi-page applications, SPAs only maintain one HTML file, commonly index.html. Instead of serving a different HTML file for each path, SPAs depend on client-side routing. React Router is a popular client-side routing library.

Routing is a process in which a user is directed to different pages based on their action or request. ReactJS Router is mainly used for developing Single Page Web Applications (SPA).  React Router is used to define multiple routes in the application. When a user types a specific URL into the browser, and if this URL path matches any 'route' inside the router file, the user will be redirected to that particular route.

Why use React router?

React Router plays an important role to display multiple views in a single page application. Without React Router, it is not possible to display multiple views in React applications. Most of the social media websites like Facebook, Instagram uses React Router for rendering multiple views.

React Router uses component structure to call components, which display the appropriate information. React router also allows the user to utilize browser functionality like the back button, and the refresh page, all while maintaining the correct view of the application.

React Router Installation

React contains three different packages for routing. These are:

1.  react-router: It provides the core routing components and functions for the React Router applications.

2.    react-router-dom: It is used for web applications design.

3.    react-router-native: It is used for mobile applications.

Step 1: Install React Router

It is not possible to install react-router directly in your application. To use react routing, first, you need to install react-router-dom modules in your application. The below command is used to install react router dom.


  npm install react-router-dom

Step 2: Make Four components.

In our project, we will create four more components in the directory called Pages along with App.js, which is already present.

Pages/Home.js

import React from "react";

export default function Home() {
  return (
    <div>
      <h1>Home Page</h1>
    </div>
  );
} 

Pages/About.js

import React from "react";

export default function About() {
  return (
    <div>
      <h1>About Page</h1>
    </div>
  );

} 

Pages/Contact.js

import React from "react";

export default function Contact() {
  return (
    <div>
      <h1>Contact Page</h1>
    </div>
  );
} 

Pages/Navbar.js

import React from "react";

export default function Navbar() {
  return (
    <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
      <div className="container-fluid">
        <ul className="nav navbar-nav">
          <li className="nav-item">
            <a href="/" className="nav-link" exact>
              Home
            </a>
          </li>
          <li className="nav-item">
            <a href="/about" className="nav-link" exact>
              About
            </a>
          </li>
          <li className="nav-item">
            <a href="/contact" className="nav-link" exact>
              Contact
            </a>
          </li>
        </ul>
      </div>
    </nav>
  );
}


Step 3: Setup App.js for Routing

App.js

import React from 'react';
import Navbar from "./Pages/Navbar";
import Home from "./Pages/Home";
import About from "./Pages/About";
import Contact from "./Pages/Contact";

function App() {
  return (
      <div className="App">
         <Navbar />
         <Home />
         <About />
         <Contact />
      </div>
  );
}

export default App; 

For Routing, open the app.js file and import all the four component files in it. Here, you need to import line: 


  import { BrowserRouter as RouterSwtichRoute } from "react-router-dom";

which helps us to implement the Routing. Now, our app.js file looks like below.

BrowserRouter as Router

First, you'll need to set up your app to work with React Router. Everything that gets rendered will need to go inside the <BrowserRouter> element, but we just rename BrowserRouter as Router only to reduce the long name of the BrowserRouter. so wrap your App in those first. It's the component that does all the logic of displaying various components that you provide it with.

import React from "react";
import { BrowserRouter as RouterSwtichRoute } from "react-router-dom";

import Navbar from "./Pages/Navbar";
import Home from "./Pages/Home";
import About from "./Pages/About";
import Contact from "./Pages/Contact";
function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <Home />
        <About />
        <Contact />
      </div>
    </Router>
  );
}
export default App;


Switch

Next, in your App component, add the Switch element (open and closing tags). These ensure that only one component is rendered at a time. It checks each route for a match sequentially and stops once the first match is found.

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <switch>
          <Home />
          <About />
          <Contact />
        </switch>
      </div>
    </Router>
  );
}

You notice that we put <Navbar /> component outside the switch, because we want that navbar will be visible on each component that render.

Route

It's now time to add your <Route> tags. These are the links between the components and should be placed inside the <Switch> tags.

To tell the <Route> tags which component to load, simply add a path attribute and the name of the component you want to load with component attribute. The <Route> will return null in case the specified URL doesn’t match the defined path.

 

function App() {
    return (
      <Router>
        <div className="App">
          <Navbar />
          <switch>
            <Route path="/" exact component={Home} />
            <Route path="/about" exact component={About} />
            <Route path="/contact" exact component={Contact} />
          </switch>
        </div>
      </Router>
    );
  }  

When the route matches /, the application shows the Dashboard component. When the route is changed by clicking the “About” link to /about, the Dashboard component is removed and the About component is inserted in the DOM.

Notice the exact attribute. Without this, path="/" would also match /about, since / is contained in the route.  However, we want  ‘/’ to match only our render function, hence using ‘exact’ explicitly achieves this.

Step 4: Adding Navigation Link

Link

Sometimes, we want to need multiple links on a single page. When we click on any of that particular Link, it should load that page which is associated with that path without reloading the web page. To do this, we need to import <Link> component in the Navbar.js file. The Link component is used to trigger new routes. You import it from react-router-dom, and you can add the Link components to point at different routes, with the to attribute. It is the equivalent of anchor tags: <a> </a>.

So now we should update Navbar.js for providing Navigation link in react application by replacing <a> tag to <Link> Tag and 'href' to 'to' attribute.  

Pages/Navbar.js

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

export default function Navbar() {
  return (
    <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
      <div className="container-fluid">
        <ul className="nav navbar-nav">
          <li className="nav-item">
            <Link to="/" className="nav-link" exact>
              Home
            </Link>
          </li>
          <li className="nav-item">
            <Link to="/about" className="nav-link" exact>
              About
            </Link>
          </li>
          <li className="nav-item">
            <Link to="/contact" className="nav-link" exact>
              Contact
            </Link>
          </li>
        </ul>
      </div>
    </nav>
  );
} 

404 Page Not Found

A common use case for when you’re building a web app is to have a “catch all” route that will be rendered if none of your other routes match. A common example of this would be a 404 page.

To create a client side "404 not found" fallback all you need to do is make use of a <Route /> component with a non-greedy matching path. Create your NotFound component, i.e. the page which will display 404 error message:

Pages/NotFound.js

import React from "react";

export default function NotFound() {
  return (
    <div>
      <h3>404 page not found</h3>
      <p>We are sorry but the page you are looking for does not exist.</p>
    </div>
  ); 

Let's add <NotFound /> component to routes configuration, using * as a value of the path parameter to get a non-greedy matching.


It is important to remember that the 404 route needs to be declared in the very bottom of your routes configuration, so the <Route /> is only mounted if any of the routes' path declared above are not matched:

App.js

import NotFound from "./Pages/NotFound";

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <switch>

          {/* Other Page Routes */}

          <Route component={NotFound} />
        </switch>
      </div>
    </Router>
  );
}
export default App; 

See the example below, try to enter some non valid url to see 404 page: