How to create dynamic pages in React Js

How to create dynamic pages using higher order components (HOC) in React Js

Posted by Ervin Adams on October 15, 2021

A higher-order component (HOC) is the advanced technique in React.js for reusing a component logic. It is a pattern created out of React’s compositional nature that privileges composition over inheritance. In this tutorial, we are going to use HOC to create basic dynamic pages. Before starting the tutorial, if you have not set up your computer to create React apps, go to this link https://wecode101.com/create-react-app to understand how.

Step 1. execute command

npx create-react-app my-app

Step 2. Edit App.js within the src directory.

These changes are taken from an earlier tutorial https://wecode101.com/how-to-create-react-nav-bar-in-react-js

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

import "bootstrap/dist/css/bootstrap.min.css";

import TabOne from "./components/TabOne.component";
import TabTwo from "./components/TabTwo.component";
import TabThree from "./components/TabThree.component";

import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
        <Router>
          <div className="container">
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
              <a className="navbar-brand" href="https://wecode101.com/" rel="noopener noreferrer" target="_blank">
                <img src={logo} width="30" height="30" alt="wecode101.com/" />
              </a>
              <Link to="/" className="navbar-brand">Home</Link> {/*Clickable links related to the Router*/}
              <div className="collpase navbar-collapse">
                <ul className="navbar-nav mr-auto">
                  <li className="navbar-item">
                    <Link to="/" className="nav-link">tab-one</Link>
                  </li>
                  <li className="navbar-item">
                    <Link to="/two" className="nav-link">tab-two</Link>
                  </li>
                  <li className="navbar-item">
                    <Link to="/three" className="nav-link">tab-three</Link>
                  </li>
                </ul>
              </div>
            </nav>
            <br/>
            <Route path="/" exact component={TabOne} />{/*The Router enables the navigation among views of various components*/}
            <Route path="/two" component={TabTwo} />
            <Route path="/three" component={TabThree} />
          </div>
        </Router>
    );
  }
}

Step 3. Add component folder within the src directory.

Add 3 components to the directory, again I will take from tutorial https://wecode101.com/how-to-create-react-nav-bar-in-react-js

All the 3 components are similar.  

Component 1

import React, { Component } from 'react';

export default class TabOne extends Component {

 render() {

   return (

     <div style={{marginTop: 10}}>

       <h3>Tab One</h3>

     </div>

    )

  }

}

Component 2

import React, { Component } from 'react';

export default class TabTwo extends Component {

 render() {

   return (

     <div style={{marginTop: 10}}>

       <h3>Tab Two</h3>

     </div>

    )

  }

}

Component 3

import React, { Component } from 'react';

export default class TabThree extends Component {

 render() {

   return (

     <div style={{marginTop: 10}}>

       <h3>Tab Three</h3>

     </div>

    )

  }

}

Step 4. Create a folder called HOC within components directory and add components below

PageHeader.js

import React from "react";

function PageHead({title, menu}) {
    return (
        <div className="row py-2 align-items-center">
            <h5 className="col-11">{title}</h5>
            <div className="ml-auto btn-group col-1">
                {menu}
            </div>
        </div>
    )
}
export default PageHead;

PageBody.js

import React from "react";

function PageBody({content}) {
    return (
        <div className="container mt-5">
            <h5>{content}</h5>
        </div>
    )
}
export default PageBody;

PageFooter.js

import React from "react";

function PageFooter() {
    return (
        <footer className="page-footer font-small special-color-dark pt-4 fixed-bottom">
            <div className="footer-copyright text-center py-3">
                <h5>Page Footer</h5>
            </div>
        </footer>
    )
}
export default PageFooter;

Step 5. Now we are going to use the components in the hoc folder as higher order components to edit the initial components.

All the components from the HOC folder are imported and used within the render function. 

Data has been passed to the PageHead and PageBody components to be displayed for the specific page. 

The HOC components are used in all of the other components, making them reusable. 

Here is an example of one of the 3 components. All the components are similar with a simple display to show the current component on display.

import React, { Component } from 'react';
import PageHead from "./hoc/PageHeader";
import PageBody from "./hoc/PageBody";
import PageFooter from "./hoc/PageFooter";
import {Dropdown} from "react-bootstrap";

export default class TabOne extends Component {
    constructor(props) {
        super(props);
        this.state = {
            headTitle: "Top One",
        };
    }

    render() {
        const menu = <Dropdown>
            <Dropdown.Toggle variant="success" id="dropdown-basic">
                Action
            </Dropdown.Toggle>

            <Dropdown.Menu>
                <Dropdown.Item href="#/action-1">Action</Dropdown.Item>
                <Dropdown.Item href="#/action-2">Another action</Dropdown.Item>
                <Dropdown.Item href="#/action-3">Something else</Dropdown.Item>
            </Dropdown.Menu>
        </Dropdown>;

        const content = "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, " +
            "that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. " +
            "These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided." +
            " But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: " +
            "he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.";

        return (
            <div>
                <div>
                    <PageHead title={this.state.headTitle} menu={menu}/>
                    <PageBody content={content} />
                    <PageFooter/>
                </div>
            </div>
        )
    }
}

Hopefully this tutorial gave some understanding of HOC and the HOC design pattern. However, HOC is used in other ways. For instance, you can use HOC to create a table that can be used in multiple components. A higher-order component (HOC) is a really useful technique in React for reusing component logic.

You can go here https://github.com/wecode101/higher-order-components-hoc-react-js to see the full project.