React application project setup -Routing in react

2020, Jan 07

In this blog we are going to setup the router. For this we will be using an open source library react-router. Creators of this library are Ryan Florence and Michael Jackson. These guys are awesome! I really like their talks on react.

If you are new to react and has not read my previous blogs the below is the list. Please go through it.

  1. React application project setup  - Installation
  2. React application project setup - II
  3. React application project setup - III

Before setting up the react-router in our project, lets discuss its need in our react application. For this, we need to understand the concept of SPA(Single Page Application). As per wiki, definition is:

A single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server.

In a simple sentence, You don't need to refresh or request the whole page when you click on any link.

You can follow this nice blog to know more about the SPA.

So, meaning of routing in an application is to move between the different parts of the application when a user clicks an element like link, button, image etc. within the application.

Let's start integrating the react-router in our project. If you are following my previous blogs then you must have repository my-react-app in your GitHub account. We will be going to create a branch feature/router-integration from our repository my-react-app and push the code to the branch.

In command line go to the project root in your system and run the below command.

git checkout -b feature/router-integration

//Switched to a new branch 'feature/router-integration'

React router library has below packages:

  1. react-router  -  This is the core library
  2. react-router-dom  -  This package is used for web applications. We are going to use it.
  3. react-router-native  -  This package is used in react native for the development of Android and iOS applications.
  4. react-router-config  -  This package provide static route configuration helpers for react-router.

There is no need to install the core react-router library by itself. Both react-router-dom and react-router-native import all the functionality of the core react-router library. For our web application we can choose react-router-dom. This library is installed in a project by running the command below.

npm install --save react-router-dom

Now, we have to decide which type of router we are going to use. For browser based applications we have 2 options.

  1. BrowserRouter: should be used when you have a server that will handle dynamic requests (knows how to respond to any possible URI). Usually it is preferable and we are going to use it.
  2. HashRouter: should be used for static websites (where the server can only respond to requests for files that it knows about).

Let's start with writing the code and then we will go through the code.

Create a file App.js inside src folder.

touch src/App.js

Add below code in the file App.js.

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom';
export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/dashboard">Dashboard</Link></li>
        </ul>
        <hr />
        <Switch>
          <Route exact path="/"><Home /></Route>
          <Route path="/about"><About /></Route>
          <Route path="/dashboard"><Dashboard /></Route>
        </Switch>
      </div>
    </Router>
  )
}
function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}

Then import App in the index.js file.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
const HelloWorld = () => {
  return (
    <div>
      <h1>Hello World!</h1>
      <App />
    </div>
  );
}
ReactDOM.render(
  <HelloWorld />,
  document.getElementById('root')
);

Application will be looking like:

app

In App.js,we have imported Switch, Router and Link from the react-router-dom.

  • Switch: A <Switch> looks through all its children <Route> elements and renders the first one whose path matches the current URL. Use a <Switch> any time you have multiple routes, but you want only one of them to render at a time.
  • Router: <Route>s can be created anywhere inside of the router, but often it makes sense to render them in the same place. Routes have three props that can be used to define what should be rendered when the route's path matches. Only one should be provided to a <Route> element.
  • component - A React component. When a route with a component prop matches, the route will return a new element whose type is the provided React component.
  • render - A function that returns a React element. It will be called when the path matches. This is similar to component, but is useful for inline rendering and passing extra props to the element.
  • children - A function that returns a React element. Unlike the prior two props, this will always be rendered, regardless of whether the route's path matches the current location.
  • Link: Our application needs a way to navigate between pages. Router provides a <Link> component to prevent that from happening. When clicking a <Link>, the URL will be updated and the rendered content will change without reloading the page.

App.js file is looking very lengthy. Let's split up the code.

We need to create different files for the Home, About and Dashboard.

touch src/Home.js src/About.js src/Dashboard.js

Then put the respective code in the files.

Home.js

import React from 'react';
function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}
export default Home;

About.js

import React from 'react';
function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}
export default About;

Dashboard.js

import React from 'react';
function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}
export default Dashboard;

Let's create the Navbar links as a separate components.

touch src/Navbar.js

Navbar.js

import React from 'react';
import {
  Link
} from 'react-router-dom';
function Navbar() {
  return (
    <ul>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/about">About</Link></li>
      <li><Link to="/dashboard">Dashboard</Link></li>
    </ul>
  );
}
export default Navbar;

Remove these code from App.js and import these components. Now the App.js file will be as below.

App.js

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Dashboard from './Dashboard';
import Navbar from './Navbar';
export default function App() {
  return (
    <Router>
      <div>
        <Navbar />
        <hr />
        <Switch>
          <Route exact path="/"><Home /></Route>
          <Route path="/about"><About /></Route>
          <Route path="/dashboard"><Dashboard /></Route>
        </Switch>
      </div>
    </Router>
  )
}

Everything is looking fine now. Let's commit and push the code to repository.

git add .

Files are added.

git commit -m "React router integration to the application"

Files are committed.

git push origin feature/router-integration

Files are pushed to the repository.

Now, code will be available in the branch feature/router-integration.

In my next blog we will look into the integration of CSS frameworks like bootstrap and material-ui with our existing react application. Later, we will see how to use the private routes for authenticated page request.