Higher Order Component in React - In depth discussion about React HOC
Categories - React Js Tags - React Js JavaScript   Maniruzzaman Akash   1 year ago   2066   0

Higher Order Component in React - In depth discussion about React HOC

Before starting to learn Higher Order Component in React, we'll learn first Higher Order Function in JavaScript. Once we know what is the Higher Order Function in JavaScript, it is pretty much simple and easier to understand the Higher Order Component in React.

 

Higher Order Function in JavaScript

Higher Order Function is a function which actually returns another function and receives a function as a parameter.

Normally a function returns a value. Value could be any type of data like int, string, array, object, null, undefined or anything.

But Higher Order function doesn't return a Value, rather it returns a Function. So, summarize would be -

  1. Accept a function as parameter
  2. Return another function

 

Benefits of Higher Order function:

  1. We can re-use same type of logic very easily using this Higher Order function. 
  2. We can pass additional argument and process easily the outputted data.

 

Let's check a simple arithematic examples using Higher Order function in JavaScript.

function sum(a, b) {
    return a + b;
}

function multiplication(a, b) {
    return a * b;
}

// result() is a Higher Order Function
function result(operation) { // operation is actually an another function
    return function(a, b) { // return function
        return "Result of operation: " + operation(a, b);
    }
}

const sumResult = result(sum);
const multipleicationResult = result(multiplication);

console.log(sumResult(1, 200)); // Result of operation: 201
console.log(multipleicationResult(2, 200)); // Result of operation: 400

Explanation:

  1. Suppose we've two independent function - sum() and multiplication(). We can add same type of many separate function which will do exactly the one task.
  2. Now, we want to get those both function result after calculation. And we want to print before something like, Result of operation:  .
  3. But we have to do these tasks repeatedly.
  4. But, rather their is a Higher Order Function in JavaScript.
  5. We create a method called result. Which accepts operation as it's parameter.
  6. Inside that function, we return an another function. Where our input values will be passed.
  7. Now, this will return with Result of operation: text.
  8. So, we can re-use the logic very beautifully using Higher Order Function.

 

Let's see a more real-life Higher Order Function example in JavaScript - 

Problem: We need a currency formatter for different language anytime used in the application. In currency formatter, it takes currencySymbol, decimalSeperator and a value. Finally returns a formatted string. We could want to pass different currency.

Solution:

/**
* Format Currency.
*
* Format the fractional part of value with currency
*/
const formatCurrency = function (currencySymbol, decimalSeparator) {
  return function (value) {
    const wholePart = Math.trunc(value / 100);
    let fractionalPart = value % 100;
    if (fractionalPart < 10) {
      fractionalPart = "0" + fractionalPart;
    }
    return `${currencySymbol}${wholePart}${decimalSeparator}${fractionalPart}`;
  };
};

const currencyDollar = formatCurrency('$', '.');
const currencyPound  = formatCurrency('£', '.');

console.log(currencyDollar(10)); // $0.10
console.log(currencyPound(10)); // £0.10

So, you can see, it's pretty much awesome that we can implement multiple currency very easily. This Higher Order Function is pretty much re-usable.

 

Higher Order Component in React

In React, Higher Order Component is a Component which return another Component and accepts a Component as Parameter.

  1. Accept a component as parameter
  2. Return another component 
  3. It's a Pure Component 
  4. Does not re-render without the change of Input Component 
  5. No Side-Effect. 

 

Example 1: Higher Order Component in React

Problem: We've separate Pages like Home Page and About Us Page. And, for every page there are some content in Header and some in Footer.

 

How Normally we do:

HomePage Component:

import React from "react";

const HomePage = () => {
  return (
    <div>
        <header>
            Some Header Content
        </header>

        <div title="Home Page">
          <h2>Home Page</h2>
        </div>

        <footer>
            Some Footer Content
        </footer>

    </div>
  );
};

export default HomePage;

 

AboutPage Component:

import React from "react";

const AboutPage = () => {
  return (
    <div>
        <header>
            Some Header Content
        </header>

        <div title="About Page">
          <h2>About Page</h2>
        </div>

        <footer>
            Some Footer Content
        </footer>

    </div>
  );
};

export default AboutPage;

But, hope you've seen the problem in here. We've repeatedly use the Header and Footer Logic in Both of the file.

 

Solution using Higher Order Component:

Now Let's make a Higher Order Component called - withLayout(). in a file like hocs/Layout.js.

import React from "react";

const withLayout = (PageComponent) => {
  return function WithPage({ ...props }) {
    return (
      <div>
        <header>
            Some Header Content
        </header>

        <!-- Called The Component Parameter -->
        <PageComponent />

        <footer>
            Some Footer Content
        </footer>

    </div>
    );
  };
};

export default withLayout;

 

Boom, Now let's implement AboutPage and HomePage component very easily.

import React from "react";
import withLayout from "./hocs/Layout";

const HomePage = () => {
  return (
    <div title="Home Page">
      <h2>HomePage</h2>
    </div>
  );
};

export default withLayout(HomePage);

 

import React from "react";
import withLayout from "./hocs/Layout";

const AboutPage = () => {
  return (
    <div title="About Page">
      <h2>About Page</h2>
    </div>
  );
};

export default withLayout(AboutPage);

 

So, now after default exporting we just do this line withLayout(ComponentName)

export default withLayout(AboutPage);

 

So, it's now very simple to implement Higher Order Component in your React project easily. If still any confusion, just comment below.

For Practice, You can check this Code-Sandbox - https://codesandbox.io/s/higher-order-component-in-react-ofd2r?file=/src/hocs/Layout.js

Previous
React Tutorials - Beginner to Pro - A Complete React Tutorial Series