React Tutorials - Day Five - Router

This is the fifth part of this series. The list of the previous articles is given below.

Today, we will learn about routing in React - how to setup routing configuration and also, how routes work in React. If we want to create a single page application, we need the routing configured so as to redirect from one page to another and read the route parameters.

To perform routing in React, we should have to install the “react-router-dom” packages. So, let’s install this package and perform some routing tasks. If you are working with the latest version of React, then use “react-router-dom” packages for routing but if you are using the older version of React, then use the “react-router” packages. Router maintains a history object that tracks the location; whenever location is changed, it re-renders the website. Coding style for both packages are different,. In this article, we will learn about the “react-router-dom” that is V4 version of routing packages.

First, install the “react-router-dom” package. For this, run the below command in your command line terminal.

npm install --save react-router-dom

React

After installing the required packages, now let's create some components and render these components using the routing as per value of generated URL.

Home.jsx

Create a “home.jsx” file inside the “home” folder and paste the following code into this file.

  1. import React from 'react';  
  2.   
  3. class Home extends React.Component {  
  4.   constructor(){  
  5.      super();  
  6.   }   
  7.    render() {      
  8.       return (  
  9.         <div>  
  10.        <p>This is Home Page</p>  
  11.          </div>  
  12.       );  
  13.    }  
  14. }  
  15.   
  16. export default Home;  

Aboutus.jsx

Create a “aboutus.jsx” file inside the “aboutus” folder and paste the following code into this file.

  1. import React from 'react';  
  2.   
  3. class AboutUs extends React.Component {  
  4.   constructor(){  
  5.      super();  
  6.   }   
  7.    render() {      
  8.       return (  
  9.         <div>  
  10.        <p>This is AboutUs Page</p>  
  11.          </div>  
  12.       );  
  13.    }  
  14. }  
  15.   
  16. export default AboutUs;   

Details.jsx

Create a “details.jsx” file inside the “details” folder and paste the following code into this file.

  1. import React from 'react';  
  2.   
  3. class Details extends React.Component {  
  4.   constructor(){  
  5.      super();  
  6.   }   
  7.    render() {      
  8.       return (  
  9.         <div>  
  10.        <p>This is Details Page</p>  
  11.          </div>  
  12.       );  
  13.    }  
  14. }  
  15.   
  16. export default Details;  

Now following will be the structure of our project.

React

After creating the all required pages now go to ”app.js” file and replace the code of this file with below code.

  1. import React from 'react';  
  2. import ReactDOM from 'react-dom';  
  3. import Main from '../main/main.jsx';  
  4. import { BrowserRouter } from 'react-router-dom'  
  5.   
  6. class App extends React.Component {  
  7.    render() {  
  8.       return (  
  9.     <BrowserRouter >  
  10.     <Main/>  
  11.     </BrowserRouter>  
  12.       )  
  13.    }  
  14. }  
  15.   
  16. ReactDOM.render(<App/>, document.getElementById('app'));  

In the above code we import the “BrowserRouter” from “react-router-dom” package. For website based routing we have two types of the router that are “BrowserRouter” and “HashRouter”. If you are working with a static website then use the “HashRouter” but if you website is hosted on a server and handle the dynamic requests then use the “BrowserRouter”, so here we are using the “BrowserRouter”. The router object keeps a history object and that is uses to keep information about the current location and re-render the website whenever history object will change.

The router object contain a single child element so it is better that we create a component that handle the rendering of all application. Here we use the “Main” component and now we implement all routing related operation in this component. Replace the code of “main.jsx” file with the following code.

Main.jsx

  1. import React from 'react';  
  2. import Footer from '../footer/footer';  
  3. import Header from '../header/header';  
  4. import  Details from '../details/details';  
  5. import  Home from '../home/home';  
  6. import  AboutUs from '../aboutus/aboutus';  
  7. import { Switch, Route } from 'react-router-dom'  
  8.   
  9. class Main extends React.Component {  
  10.   constructor(){  
  11.      super();   
  12.    }  
  13.    render() {  
  14.           return (  
  15.           <div>  
  16.            <Header></Header>  
  17.     <Switch>  
  18.       <Route exact path='/' component={Home}/>  
  19.       <Route path='/details' component={Details}/>  
  20.       <Route  path='/aboutus' component={AboutUs}/>  
  21.     </Switch>  
  22.   
  23.          </div>  
  24.       );  
  25.    }  
  26. }  
  27.   
  28. export default Main;  

In the above code, we have created three routes for the application. Route element takes a path parameter and match this path value to url of the application and render the application to a new React element. For example “<Route path=’/details’ component={Details} />” route element match the “/details” path and if path is matched it will render the “Details” component. Point to notice that all the route elements are placed inside the “Switch” element. The “Switch” element returns the first “Route” element that matches the location. In the absence of the “Switch” element you will get all the “Route” elements that match the location.

After defining the routes for the application, let’s create some link element that will be use to navigate throughout the application. You can see that we use the “Header” as child component into “Main” component. We define our “link” elements into “Header” component. Now open your “header.jsx” file and paste the following code into this file.

Header.jsx

  1. import React from 'react';  
  2. import { Link } from 'react-router-dom'  
  3.   
  4. class Header extends React.Component {  
  5.     
  6.   constructor(){  
  7.      super();  
  8.   }  
  9.     
  10.     
  11.    render() {  
  12.       
  13.       return (  
  14.         <div>  
  15.         <ul>  
  16.         <li><Link to='/' >Home</Link></li>  
  17.         <li><Link to='/details' >Details</Link></li>  
  18.         <li><Link to='/aboutus'>AboutUs</Link></li>     
  19.               
  20.         </ul>  
  21.   
  22.          </div>  
  23.       );  
  24.    }  
  25. }  
  26.   
  27. export default Header;  

In the “Header” component, we did create three “Link” elements, each link element takes the “to” property that defines the “location” for the application. After making all the changes now save and refresh your browser. Now the following will be the output on your screen.

React
React
React
After creating all the “Routes” and “Link” elements now it is very easy to understand how react routing works. When you click on any “Link” element it will change the URL of application and if any routes match this URL then corresponding component will re-render.

Pass Routing Parameters

After creating some simple routes now we will learn how pass parameter with routes and how to access these paths in a component.

Header.jsx 

  1. import React from 'react';  
  2. import { Link } from 'react-router-dom'  
  3.   
  4. class Header extends React.Component {  
  5.     
  6.   constructor(){  
  7.      super();  
  8.   }  
  9.     
  10.     
  11.    render() {  
  12.       
  13.       return (  
  14.         <div>  
  15.         <ul>  
  16.         <li><Link to='/' >Home</Link></li>  
  17.         <li><Link to='/details' >Details</Link></li>  
  18.         <li><Link to='/aboutus/120'>AboutUs</Link></li>     
  19.         </ul>  
  20.          </div>  
  21.       );  
  22.    }  
  23. }  
  24.   
  25. export default Header;  

Main.jsx 

  1. import React from 'react';  
  2. import Footer from '../footer/footer';  
  3. import Header from '../header/header';  
  4. import  Details from '../details/details';  
  5. import  Home from '../home/home';  
  6. import  AboutUs from '../aboutus/aboutus';  
  7. import { Switch, Route } from 'react-router-dom'  
  8.   
  9. class Main extends React.Component {  
  10.   constructor(){  
  11.      super();   
  12.    }  
  13.    render() {  
  14.           return (  
  15.           <div>  
  16.            <Header></Header>  
  17.            <Switch>  
  18.       <Route exact path='/' component={Home}/>  
  19.       <Route path='/details' component={Details}/>  
  20.       <Route  path='/aboutus/:id' component={AboutUs}/>  
  21.       </Switch>  
  22.       </div>  
  23.       );  
  24.    }  
  25. }  
  26.   
  27. export default Main;  

Aboutus.jsx 

  1. import React from 'react';  
  2.   
  3. class AboutUs extends React.Component {  
  4.   constructor(props){  
  5.      super();  
  6.     this.studentId=props.match.params.id;   
  7.   }   
  8.    render() {      
  9.       return (  
  10.         <div>  
  11.        <p>This is AboutUs Page</p>  
  12.        <h3> Student Roll No Is: {this.studentId}</h3>  
  13.          </div>  
  14.       );  
  15.    }  
  16. }  
  17.   
  18. export default AboutUs;  

In “header.jsx” file we define the “Link” element that render the “aboutus/120” URL.

React

To access this URL now we need to define a “Route” element into “Main.jsx” that will match this URL and render a new component.

React

At component level we can access this route value using the “prop.match.params” property.

React

Now, when you click on “Aboutus” link, you will get the following output.

React
Navigating Programmatically

So far, we have navigated throughout our application using the “Link” element. Now, let us learn how to navigate programmatically. For this, we will create a button into “details” component and on click event of this button, we will navigate to the “aboutus” component.

Details.jsx

  1. import React from 'react';  
  2. import { Router } from 'react-router';  
  3. class Details extends React.Component {  
  4.   constructor(props){  
  5.      super();  
  6.      this.navigateProgramatically = this.navigateProgramatically.bind(this);  
  7.   }   
  8.    navigateProgramatically() {  
  9.     this.props.history.push('/aboutus/1500');  
  10.   }  
  11.   
  12.    render() {      
  13.       return (  
  14.         <div>  
  15.        <p>This is Details Page</p>  
  16. <button onClick={this.navigateProgramatically}>Change Root</button>  
  17.          </div>  
  18.       );  
  19.    }  
  20. }  
  21.   
  22.   
  23. export default Details;  

In the above code, we created a button and on click event of this button, we are changing the history object of routes and pushing a new location into history object. After making all the above changes the following will be the output of “details” page.

React
When you click on “Change Root” button, you will redirect to the “aboutus” page.

React
Render types of <Route> 

Each Route element has three types of the properties that define what types of the result will render. These three types of the properties are

  • Component
  • Render
  • Children

Component

React

In the above example we use the “component” property of router, which means whenever the Route will match a new component there will be a re-render.

Render

Render property is similar to the component but it is used for inline rendering and we can pass the extra properties to component. Let’s take an example.

Main.jsx

  1. import React from 'react';  
  2. import Footer from '../footer/footer';  
  3. import Header from '../header/header';  
  4. import  Details from '../details/details';  
  5. import  Home from '../home/home';  
  6. import  AboutUs from '../aboutus/aboutus';  
  7. import { Switch, Route } from 'react-router-dom'  
  8.   
  9. class Main extends React.Component {  
  10.   constructor(){  
  11.      super();  
  12.      this.age=12000;   
  13.    }  
  14.    render() {  
  15.           return (  
  16.           <div>  
  17.            <Header></Header>  
  18.            <Switch>  
  19.       <Route exact path='/' component={Home}/>  
  20.   
  21.       <Route path='/details' render={(props) => (  
  22.         <Details  data={this.age}/>  
  23.         )}/>  
  24.           
  25. <Route  path='/aboutus/:id' component={AboutUs}/>  
  26.       </Switch>  
  27.       </div>  
  28.       );  
  29.    }  
  30. }  
  31.   
  32. export default Main;  

In the above code for “/details” path we define the “render” property and assign a “data” property . Now we can access this “data” property in our “Details” component.
React
Details.jsx

  1. import React from 'react';  
  2. import { Router } from 'react-router';  
  3. class Details extends React.Component {  
  4.   constructor(props){  
  5.      super();  
  6.      this.navigateProgramatically = this.navigateProgramatically.bind(this);  
  7.   }   
  8.    navigateProgramatically() {  
  9.     this.props.history.push('/aboutus/1500');  
  10.   }  
  11.   
  12.    render() {      
  13.       return (  
  14.         <div>  
  15.        <p>This is Details Page</p>  
  16.        <h2>{this.props.data}</h2>  
  17. <button onClick={this.navigateProgramatically}>Change Root</button>  
  18.          </div>  
  19.       );  
  20.    }  
  21. }  
  22.   
  23.   
  24. export default Details;  

Output

React
Children

This property is a little bit different from the prior two properties, the children property always renders regardless of whether the path is matched or not. Let’s take an example.

Main.jsx

  1. import React from 'react';  
  2. import Footer from '../footer/footer';  
  3. import Header from '../header/header';  
  4. import  Details from '../details/details';  
  5. import  Home from '../home/home';  
  6. import  AboutUs from '../aboutus/aboutus';  
  7. import { Switch, Route } from 'react-router-dom'  
  8.   
  9. class Main extends React.Component {  
  10.   constructor(){  
  11.      super();  
  12.      this.age=12000;   
  13.    }  
  14.    render() {  
  15.           return (  
  16.           <div>  
  17.            <Header></Header>  
  18.          
  19.       <Route exact path='/' component={Home}/>  
  20.   
  21.       <Route path='/details' render={(props) => (  
  22.         <Details  data={this.age}/>  
  23.         )}/>  
  24.        
  25. <Route path='/aboutus/:id' children={(props) => (  
  26.   props.match  
  27.     ? <AboutUs data={props.match} />  
  28.     : <Details  data={this.age}/>  
  29. )}/>     
  30.         
  31.       </div>  
  32.       );  
  33.    }  
  34. }  
  35.   
  36. export default Main;  

Aboutus.jsx

  1. import React from 'react';  
  2.   
  3. class AboutUs extends React.Component {  
  4.   constructor(props){  
  5.      super();  
  6.     this.studentId=props.data.params.id;   
  7.   }   
  8.    render() {      
  9.       return (  
  10.         <div>  
  11.        <p>This is AboutUs Page</p>  
  12.        <h3> Student Roll No Is: {this.studentId}</h3>  
  13.          </div>  
  14.       );  
  15.    }  
  16. }  
  17.   
  18. export default AboutUs;  

In “Main.jsx” file we define the “children” property for the route, this Route will render the “AboutUs” component if it matches the path otherwise it will return the “Details” component.

React

Now when you save the above changes and refresh your browser you will get the following output.

React
React
React
Conclusion

In this article, we learned about React routing. In our next article, we will learn about Flux. If you have any queries or doubts, please mention them in the comments section.

You can download the latest source code of this project from GitHub. Given below is the link of repository.


Similar Articles