Skip to main content

ReactJS Routing And Single Page Application Tutorial

React Router: ReactJS Single Page Application

Why do we need React Router

Nowadays single page application is the most popular. For making single page application, we need to react router. Single page application is very powerful and provides performance features as well.
What is React Router
React router is a library, it provides routing feature through which we can redirect from one page to another page.
Mainly there are two types of routing.
1. Browser Specific routing: In general or e-commerce web application have browser routing and it helps in search engine optimization. npm command to install routing package npm install react-router --save . --save is used to save the package entry in project specific package.json file.
import React from 'react';
import ReactDOM from "react-dom";
import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router';
import Home from './Home';
import About from './About';
import Contact from './Contact';
import APP from './App';
import PageNotFound from './PageNotFound';
ReactDOM.render(
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="home" component={Home} />
      <Route path="about" component={About} />
      <Route path="contact" component={Contact} />
      <Route path="*" component={PageNotFound} />
    </Route>
  </Router>,
  document.getElementById("root")
);

2. Non Browser/DOM Specific routing
This type of routing is used in banking and finance web application. Banking and finance application have DOM based routing. In this routing user will redirect form one page/step to another page/step but in browser url will not change.
NPM command to install the Package: npm install react-router-dom --save
routes.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import HomePage from './HomePage';
import AboutUsPage from './AboutUsPage';
import PageWrapper from './PageWrapper';

const Routes = () => {
  <Switch>
    <Route
      exact
      path={"pages/home"}
      key="home-page"
      render={props => {
        let Component = PageWrapper(HomePage);
        return <Component {...props} />;
      }}
    />
    {/* if you don't want to use High Order Component. You can render comonent as
    mentioned below
    <Route
      exact
      path={"pages/home"}
      key="home-page"
      render={return <HomePage/>}
    />    
    */}
    <Route
      exact
      path={"pages/about"}
      key="aboutus-page"
      render={props => {
        let Component = PageWrapper(AboutUsPage);
        return <Component {...props} />;
      }}
    />
  </Switch>;
};
export default Routes;

Here, PageWrapper is the High Order Component (HOC). HOC is the component which is useful in case we want to reuse the common component logic across the other components. All the component render by using HOC PageWrapper component. We will discuss later about HOC in detail.
layoutPage.js
import React, { Component } from 'react';
import Routes from './routes';
import AppLayoutPage from './appLayoutPage';

class LayoutPage extends Component {
  render() {
    return (
      <AppLayoutPage>
        <Routes />
      </AppLayoutPage>
    );
  }
}
export default LayoutPage;

Here Routes component is used as child component in LayoutPage component.
appLayoutPage.js
import React, { Component } from 'react';
import Header from './header';
import Footer from './footer';

class AppLayoutPage extends Component {
  render() {
    const { children } = this.props;
    return (
      <div>
        <Header />
        {children}
        <Footer />
      </div>
    );
  }
}
export default AppLayoutPage;

Here, In this component, there are three section of this page. Header and Footer components are common component for all the pages. Children, Routes component will decide which will be the children of this component.

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import AppLayoutPage from './appLayoutPage';
import './index.css';

ReactDOM.render(<AppLayoutPage />,
 document.getElementById('root'));

Here root is a element id which is mentioned in index.html file.

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

Page navigation in reactjs from one page to another page

Mainly page navigation can be done with two different ways
1. By using Link
import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class AppLayout extends Component {
  render() {
    return (
      <div>
        <Link to="/home">Home</Link>
        <Link to="/contact">Contact</Link>
        <Link to="/about">About US</Link>
      </div>
    );
  }
}
export default AppLayout;
2. Programmatically based on action/event
import React, { Component } from "react";
import { Link } from "react-router-dom";

class AppLayout extends Component {
  navigate = () => {
    const { history } = this.props;
    history.push("/contact");
    //contact is the route path
  };

  render() {
    return (
      <div>
        <button onClick={this.navigate}>Navigate</button>
      </div>
    );
  }
}
export default AppLayout;

There are multiple ways to redirect form one page to another page, here I am using push method of history.
We can also use react-router-redux for routing. I'll explain it later in detail.
Notes:There are some points which we can be follow in react as standard.
1. We should avoid to use this.props or this.state with each and every property. Follow this syntax const {history, path, any}=this.props or this.state;
2. Avoid to import useless library. Import only those which are required.
3. Don't use export with class at the top level. Use it below as export default className. It will be useful when we will connect component with redux.
4. Function can be bind with different ways as using Bind() function and arrow function (=>).
Arrow Function
import React, { Component } from "react";
import { Link } from "react-router-dom";

class AppLayout extends Component {
 //arrow function
  navigate = () => {
    const { history } = this.props;
    history.push("/contact");
    //contact is the route path
  };

  render() {
    return (
      <div>
        <button onClick={this.navigate}>Navigate</button>
      </div>
    );
  }
}
export default AppLayout;

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

class AppLayout extends Component {
    constructor(props){
        super(props);
        this.navigate=this.navigate.bind(this);
    }

  navigate(){
    const { history } = this.props;
    history.push("/contact");
    //contact is the route path
  };

  render() {
    return (
      <div>
        <button onClick={this.navigate}>Navigate</button>
      </div>
    );
  }
}
export default AppLayout;

Bind function without binding in constructor
import React, { Component } from "react";
import { Link } from "react-router-dom";

class AppLayout extends Component {
  navigate(){
    const { history } = this.props;
    history.push("/contact");
    //contact is the route path
  };

  render() {
    return (
      <div>
        <button onClick={this.navigate.bind(this)}>Navigate</button>
      </div>
    );
  }
}
export default AppLayout;

We don't need to bind the function in case we are using ES5. We need to bind function in ES6 or above version. If we don't bind function in ES6, scope will not be available and all the props and state will be undefined. That's why we need to bind.
5. All the events in html will be in camel case i.e. onClick, onFocus etc.
6. Follow the pascal case for component name and folder name i.e. HomePage, ContactPage etc.
7. Follow the camel case for component file name i.e. homePage.js, contactPage.js etc.
There is no hard and fast rule to follow the above points. in any case code will work but for making code readable and standard we should follow above points.
Please comment me if anyone need more clarification for any point.

Comments

Popular posts from this blog

React Redux Tutorials: React Redux Data Flow and Redux Lifecycle Methods With Examples

React Redux Data Flow and Redux Lifecycle Methods Overview What is Redux and why do we need Redux Redux is an open source JavaScript library which is designed for maintaining application state. Redux JS is a powerful and popular library nowadays. The command to install Redux library npm install redux --save . Nowadays JavaScript single-page applications are very popular and powerful. As the requirements for single-page applications have become complicated, our code must manage more state than ever before. This state can include server responses and cached data, as well as locally generated data that has not yet been persisted to the server. Front-end state is also increasing in complexity, as we need to manage active routes, selected tab, spinners, pagination controls etc. That's why we need Redux. click here to learn React Redux Architecture, folder structure. Three Principles of Redux: Changes are made with pure functions You write pure reducers to specify

React Redux Application Structure, Architecture and React Folder Structure Best Practices

React Redux Application Structure, Architecture and  React Folder Structure Best Practices: There some questions comes our mind when we are going to create a new react redux application structure from scratch. What folder structure should be followed especially when we are implementing a large react redux application . How to connect react with redux  What should be the naming convention of folder and react js files. What are the best practices of react redux project structure. The structure might be different for each of us but I am sharing the standard react redux application structure which is followed by most of the UI developers in IT industry. High Level React Redux Application Architecture There are many folders and files in above application screen shot, let discuss one by one. The application name is REACTWEBAPP and folders are config, public, script, server, src, reducers, sagas, store and package.json. Config: react redux application configurations