In the above code, We have the original component as TonyStark, and withIronSuit is a function that will enhance TonyStark, and return a new component, IronMan.
Further, we will discuss the implementation of higher-order components.
Why do we need higher-order components?
To understand why we need higher-order components, we will implement a react app with two counter buttons. When we click on the button, it will display the number of times it has been clicked.
The implementation will have to maintain a state variable for storing the count of how many times a button is clicked, and also, we will create a function to increment the count variable.
App.js
In App.js, we separately use the Counter1 and Counter2 components to get the functionality of buttons, as shown above.
importReactfrom'react';
import'./App.css';
importCounter1from'./components/Counter1';
importCounter2from'./components/Counter2';
functionApp() {
return (
<divstyle={{textAlign:"center"}}>
<h1>Higher-Order Components in React</h1>
<Counter1/>
<Counter2/>
</div>
);
}
exportdefaultApp;
Counter1.js
We define a separate state of the Counter1 button, and it includes the state variable count and the increment count function in it.
Similar to the implementation done in the Counter1.js, The component, Counter2 also has its state variable count and the function incrementCount in it.
In the naive implementation, we can observe that the code is getting repeated in Counter1.js and Counter2.js. This is not desirable and leads to a large amount of code in our codebase. This also leads to complications.
Till this point, you might be thinking that this is what we know that render props in React can solve. But it can solve this problem when we have a situation where we can have a Wrapper class, as shown below.
But what if the situation is as shown below, then we cannot use “render props.”
Therefore, In these cases, there is a need for higher-order components.
For more information about react framework and front end development, get into the entire our react js course.
Now, we will look at the better version of implementation that uses higher-order components in react.
How to implement higher-order components?
In this implementation, we use the withCounter.js file, which contains our higher-order component. Below is the explanation of the flow of code.
App.js
From App.js, we use our Counter1 and Counter2 components.
importReactfrom"react";
import"./App.css";
importCounter1from"./components/Counter1";
importCounter2from"./components/Counter2";
functionApp() {
return (
<divstyle={{ textAlign: "center" }}>
<h1>Higher-Order Components</h1>
<Counter1 />
<Counter2 />
</div>
);
}
exportdefaultApp;
withCounter.js
This is the higher-order component, where we have an EnhancedComponent that takes in OriginalComponent and returns a NewComponent with modifications.
Also, we have state variable count and incrementCount function in this component. It is the common functionality needed by other components, namely over here Counter1 and Counter2.
importReact, { Component } from"react";
constEnhancedComponent=OriginalComponent=> {
classNewComponentextendsComponent {
state= { count: 0 };
incrementCount= () => {
this.setState({
count: this.state.count+1,
});
};
render() {
return (
<OriginalComponent
count={this.state.count}
incrementCount={this.incrementCount}
/>
);
}
}
returnNewComponent;
};
exportdefaultEnhancedComponent;
Counter1.js
In Counter1.js, we will retrieve the props passed from withCounter component. This component will then use these props to display content.
importReact, { Component } from"react";
importEnhancedComponentfrom"./withCounter";
exportclassCounter1extendsComponent {
render() {
const { count, incrementCount } =this.props;
return (
<div>
<button
style={{ color: "red", fontSize: "40px" }}
onClick={incrementCount}
>
Clicked {count} times
</button>
</div>
);
}
}
exportdefaultEnhancedComponent(Counter1);
Counter2.js
Similar to Counter1.js, we retrieve the props and then display them. This way, we do not need to create different state variables and functions for multiple components.
importReact, { Component } from"react";
importEnhancedComponentfrom"./withCounter";
exportclassCounter2extendsComponent {
render() {
const { count, incrementCount } =this.props;
return (
<div>
<button
style={{ color: "blue", fontSize: "40px" }}
onClick={incrementCount}
>
Clicked {count} times
</button>
</div>
);
}
}
exportdefaultEnhancedComponent(Counter2);
Output
This way, we avoided code repeatability and used higher-order components for reusing the same code for various components.
Frequently Asked Questions (FAQs)
What are higher-order components? A higher-order component is a pattern where a function takes a component as an argument and returns a new component.
What is the need for higher-order components? A higher-order component is used to improve code reusability among components. It is a more general approach than render props. What is the relationship between the enhanced component and the original component? In higher-order components, an enhanced component is an original component that is modified by a higher-order function. The higher-order component defines the relationship between them.
Key Takeaways
We learned about the concept of higher-order components in react. This is an advanced concept of React that promotes code reusability. This article also explained why there is a need for higher-order components specifically. We also learned about the implementation of higher-order components in react.
Apart from this, you can also expand your knowledge by referring to these articles on Javascript and React.