What is Higher Order Component (HOC) in React JS?
Published: 2022-01-31 16:20:17

Higher order component simply explained

When it comes to advanced topics in React. you must have heard about the HOC(Higher Order Component). Now this HOC is not that much complex to learn but avoid learning it directly by taking complex example.

Now first of all let's see what kind of problem HOC solves?

Well, sometimes we have two different components which implements same logic such as,

As you can see below,

HOC example

Now for both of this components they have the same logic like counter.

Now let's see the definition of HOC which mentioned in the ReactJS.Org

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.

Now as mentioned above we can implement logic of component in single HOC and then we can use it in required components.

Let's see how this HOC is a pattern that emerges from React's compositional nature and not a part of React API.

import React, { Component } from "react";

const HOC = (Component, data) => {

//You can do modification in data then pass it to the component

  return class extends React.Component {
    render() {
      return (
        <Component />
      );
    }
  };
};

export default HOC;

As you can see this is one of the pattern of HOC component where, It takes two arguments one is component in which we want to add logic and second argument is data. We can modify this data and then can pass it to the component. Now this HOC will return a React component which returns more Enhanced Version of component

Let's try it in our likes and comments component. Both of them is using the same logic as we use in the counter.

So create new file called Hoc.js and write below code.

import React, { Component } from "react";

const HOC = (Component, data) => {
  //console.log("data", data);

  return class extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        count: data,
      };
    }

    handleClick = () => {
      this.setState({
        count: this.state.count + 1,
      });
    };

    render() {
      return (
        <Component
          
          CountNumber={this.state.count}
          handleCLick={this.handleClick}
        />
      );
    }
  };
};

export default HOC;

Here we have implemented logic for counter.

Line no 3: we can pass component and data.

Line no 6: Returns a React component.

Line no 7 to 19: This lines represents the same logic we use to implement counter.

Line no 25: Here we have pass state of the counter.

Line no 26: Here we have passed a function to increment counter state.

Now let's see how we can use this HOC.

Below is the like component.


Line no 8: To display no of likes.

Line no 9: Button to increment likes.

Line no 15: Here we have used the HOC component. We have passed our Likes Component and no 5. Why 5? because let's assume that there are already 5 likes then we can implement counter logic from no 5.

Line no 17: Here we will export the new Enhanced likes component returned by HOC.

Now in simple terms, HOC took LikesComopnent and data then returned an enhanced LikesComopnent by implementing Counter logic in it.

We can do the same for CommentComponent,

import React, { Component } from "react";
import HOC from "./HOC";

class CommentsCount extends Component {
  render() {
    return (
      <div>
        Total Comments : {this.props.CountNumber} <br />
        <button onClick={this.props.handleCLick}>Add Comment!</button>
      </div>
    );
  }
}

const EnhancedComments = HOC(CommentsCount, 10);

export default EnhancedComments;

Line 15: Here we are sending different data. (10 instead of 5)

Don't forget to call enhanced Version of component that you have exported in your component file. Just like this,

import React from "react";
import "./App.css";
import EnhancedLikes from "./components/HOC/LikesCount";
import EnhancedComments from "./components/HOC/CommentsCount";

function App() {
  return (
    <div className="App">
      <EnhancedLikes />
      <EnhancedComments />
    </div>
  );
}

export default App;

After implementing this you will understand that we don't have to write the same logic for more components.

There are many uses of HOC like,

If the user has already logged in and you want to check the user's login status in more then one component or pass the user's data then you can pass it to HOC then wrap HOC component around those components.