Higher Order Component in React.js

Higher Order Component in React.js

Higher Order Component (HOC) is an advanced technique in React.js. I try to explain this in very simple words with examples.

Now, we should know what is HOC and what problems can be solved in real life using HOC?

Higher Order Component is a function that received a component and returns a new component.

It might be confusing now but it will be clear in the example. HOC helps the developers to reuse the component logic. It also helps to avoid the props drilling problem.

Now, we try to assume a real-life problem and also try to solve this using HOC.

A student and a Teacher have different responsibilities in a school. But they have to come to school every day. We want to count how many days the teacher and student come in a month. To solve this problem, we can create two individual counter buttons, when they come to school, click the button. We will use HOC in the code to do this. I will explain step by step for beginners. Create a new react project npx create-react-app hoc. Then create two files in the src folder, student.js and teacher.js. Create a new folder in the src folder named HOC and create a file named activity.js in the HOC folder. Now our environment is ready. (You can change files and folders name. I create this environment according to our real-life problem)

We go to the student.js file and create a functional component. Write code for a button that represents whether the student is present or not. If the student is present we click on this button and counter count this.

//student.js
import React from 'react';
const Student = () => {
return (
<div>
//counter
<h3>Student present count:</h3>
//button
<button>Student present</button>
</div>
);
};
export default Student;

We write the same code in the teacher.js file

//teacher.js
import React from 'react';
const Teacher = () => {
return (
<div>
<h3>Teacher present count:</h3>
<button>Teacher present</button>
</div>
);
};
export default Teacher;

Don't forget to import the student.js and teacher.js files in the app.js

//app.js
import Student from './pages/Student';
import Teacher from './pages/Teacher';
function App() {
return (
<div>
<Student/>
<Teacher/>
</div>
);
}
export default App;

Now, run the project. Write npm start on your terminal.

Buttons are not working. So, we have to write code for buttons. We create a state to save the counter value and write a function for button functionality. Declare a state named present. This state saves the counter value. presentHadler is an event handler that contains the button functionality. Now if the student comes to school every day, then the total count will be 30 after a month. It's very easy logic, right?

//student.js
import React, { useState } from "react";
const Student = () => {
// declare a state to save value
const [present, setPresent] = useState(0);
//button functionality
const presentHandler = () => {
setPresent(present + 1);
};
return (
<div>
<h3>Student present count:{present}</h3>
<button onClick={presentHandler}>Student present</button>
</div>
);
};
export default Student;

The same logic is applied to the teacher.

//teacher.js
import React, { useState }from 'react';
const Teacher = () => {
// declare a state to save value
const [present, setPresent] = useState(0);
//button functionality
const presentHandler = () => {
setPresent(present + 1);
};
return (
<div>
<h3>Teacher present count:{present}</h3>
<button onClick={presentHandler}>Teacher present</button>
</div>
);
};
export default Teacher;

Initially, our problem is solved. But think, if we want to know the attendance of every staff in a school, then we have to write state and button event handler in every file. It is a very hard and boring task for developers.

HOC comes with a solution to this problem.

As I mentioned before, HOC is a function. So, we write a function named activity in the activity.js file and also write a functional component named Staff in the activity function. Then we write the common codes in the Staff components. I will explain the codes line by line. Nothing to worry about.

//activity.js
import React, { useState } from "react";

const activity = (Member) => {
const Staff = () => {
const [present, setPresent] = useState(0);
const presentHandler = () => {
setPresent(present + 1);
};
return (
<Member present={present} presentHandler={presentHandler}/>
);
};
return Staff;
};
export default activity;

Write a function named activity. Member is the parameter of this function. Member represents the components that are connected to the HOC function. In this case, Member represents student and teacher components. (How student and teacher components connected to HOC function, I will explain this in the next section of this blog).

Then create a functional component in the activity function and write the state and presentHandler function (the reusable parts of your code). Send state value and event handler as props to the Member. Now, student and teacher components can access these data. Return the functional component to the main function.

It is time to connect the student and teacher components with the HOC function. Just import the HOC file in the student component and add this file to the default export line.

//student.js
import React from "react";
import activity from '../Hoc/activity';
const Student = (props) => {
return (
<div>
<h3>Student present count:{props.present}</h3>
<button onClick={props.presentHandler}>Student present</button>
</div>
);
};
export default activity(Student);

teacher.js file connects to the HOC function

//teacher.js
import React from 'react';
import activity from '../Hoc/activity'

const Teacher = (props) => {
return (
<div>
<h3>Teacher present count:{props.present}</h3>
<button onClick={props.presentHandler}>Teacher present</button>
</div>
);
};
export default activity(Teacher);

It's done. We write state and event handler in the activity file. But student and teacher components can access this logic. This is Higher Order Component.

If any other components send props to the student and teacher component, they can't receive this directly. This data(props) goes to the activity function, the activity function sends this data as props to the components.

Let's jump into the code to explore this. From app.js we send some props to the student and teacher component

//app.js
import Student from './pages/Student';
import Teacher from './pages/Teacher';
function App() {
return (
<div>
<Student fee="fee"/>
<Teacher salary="salary"/>
</div>
);
}
export default App;

Now activity function receives these props.

//activity.js
import React, { useState } from "react";
const activity = (Member) => {

const Staff = (props) => {
const [present, setPresent] = useState(0);
const presentHandler = () => {
setPresent(present + 1);
console.log(present);
};
return (
<Member present={present} presentHandler={presentHandler} {...props}/>
);
};
return Staff;
};
export default activity;

Staff functional component receives props, destructures the props, and sends them to the child components. Now student and teacher components can access their own props data.

// student.js
import React from "react";
import activity from '../Hoc/activity';
const Student = (props) => {
return (
<div>
<h3>Student present count:{props.present}</h3>
<h6>Student responsibility:{props.fee}</h6>
<button onClick={props.presentHandler}>Student present</button>
</div>
);
};
export default activity(Student);
//teacher.js
import React from 'react';
import activity from '../Hoc/activity'
const Teacher = (props) => {
return (
<div>
<h3>Teacher present count:{props.present}</h3>
<h6>Teacher responsibility:{props.salary}</h6>
<button onClick={props.presentHandler}>Teacher present</button>
</div>
);
};
export default activity(Teacher);

I really hope, you understand the topic. Please try to write this code in your editor. That's will be more helpful for you.

Git-repo: github.com/alaminsahed/react-advance/tree/m..