Higher Order Components In Reactjs

Before we start learning about the Higher-order component (HOC), first we’ll see what Higher-order functions are.
 
Let’s take a simple code,
  1. const sum= (number1,number2)=>{  
  2.    return number1 + number2;  
  3. }  
The above function is simple, it accepts two input numbers and returns the sum of those two numbers.
 
Now we can take another function,
  1. const calculator = (operationType) => {  
  2.     if (operationType === “sum”) {  
  3.         return sum;  
  4.     }  
  5. }  
The above function is a higher order function, because it accepts an input string as “sum” and returns the sum functions. We can test this by console the result.
  1. Console.log( calculator(“sum”)(2,5));  // returns 7  
Here, calculator is the first level function, which accepts “sum” as a string, which return another function, by passing input values (2, 5) to that function, finally it’ll return 7. So here the calculator function is a higher order function.
 
The same concept for Higher-order component (HOC).
 
According to the React documentation (react.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.”
 
Simply, a higher-order component is a function that takes a component and returns a new component. Whereas a component transforms props into UI, a higher-order component transforms a component into another component.
  1. Const EnchancedWrappedComponent = higherOrderComponent(WrappedComponent);  
Here, where the higherOrderComponent is HOC Component that adds some additional functionality to the original component which is WrappedComponent and return an EnchancedWrappedComponent.
 
HOC in simple terms,
  • It is a component.
  • Which takes two arguments, first is a component and 2nd is a data.
  • Then it returns a new component.
  • The returned component is an enhanced version of the component that we have passed.
Let’s take two components, LikesCount and CommentsCount
 
LikesCount.js
  1. Export default class LikesCount extends component {  
  2.     Constructor(props) {  
  3.         This.state = {  
  4.             Likes: 0  
  5.         }  
  6.     }  
  7.     handleClick = () => {  
  8.         this.setState({  
  9.             likes: this.state.likes + 1  
  10.         })  
  11.     }  
  12.     Render() {  
  13.         Return( < div > {  
  14.             this.state.likes  
  15.         } < br / > < button onClick = {  
  16.             this.handleClick  
  17.         } > Like < /button> < /div>)  
  18.     }  
  19. }  
CommentsCount.js
  1. Export default class CommentsCount extends component {  
  2.     Constructor(props) {  
  3.         This.state = {  
  4.             comments: 0  
  5.         }  
  6.     }  
  7.     handleClick = () => {  
  8.         this.setState({  
  9.             comments: this.state.comments + 1  
  10.         })  
  11.     }  
  12.     Render() {  
  13.         Return( < div > {  
  14.             this.state.comments  
  15.         } < br / > < button onClick = {  
  16.             this.handleClick  
  17.         } > Add Comment < /button> < /div>)  
  18.     }  
  19. }  
App.js
  1. Function App(){  
  2.    Return(  
  3.    <div>  
  4.       < LikesCount/>  
  5.       < CommentsCount/>  
  6.    </div>  
  7.    )  
  8. }  
If you run this code, we can see the total number of likes and comments, initially 0, and the button click action will increment both by 1.
 
Now, if we see here both are following the same logic, which means both comments are doing increments of the count by 1 on every button click action.
 
Two things we can consider here, duplicate code for same logic and for large enterprise websites it may a performance issue.
 
So, by using HOC concept we can simplify this code very simple and understandable.
 
Let create a new component HOC.js
  1. Const HOC = (Component, data) => {  
  2.         Return class extends component {  
  3.             Constructor(props) {  
  4.                 This.state = {  
  5.                     Count: 0  
  6.                 }  
  7.             }  
  8.             handleClick = () => {  
  9.                 this.setState({  
  10.                     Count: this.state.Count + 1  
  11.                 })  
  12.             }  
  13.             Render() {  
  14.                 Return( < Component CountNumber = {  
  15.                         this.state.count  
  16.                     }  
  17.                     handleClick = {  
  18.                         this.handleClick  
  19.                     }  
  20.                     />)  
  21.             }  
  22.         }  
The above code accepts two arguments, the first one is component and 2nd is data. Then we applied the same logic which was already available in the other two components.
 
Let’s rewrite the LikesCount and CommentsCount components to run with this HOC component.
 
LikesCount.js
  1. Import HOC from “./HOC”;  
  2. class  LikesCount extends component {  
  3.    Render(){  
  4.       Return(  
  5.          <div>  
  6.             {this.props.CountNumber }<br/>  
  7.             <button onClick={this.props.handleClick}>Like</button>  
  8.          </div>  
  9.          )  
  10.       }  
  11.    }  
  12. Const enhancedLikesCount = HOC(LikesCount); // we created new component which uses the HOC Component.   
  13. Export default enhancedLikesCount;  
CommentsCount.js
  1. Import HOC from“. / HOC”;  
  2. class CommentsCount extends component {  
  3.    Render(){  
  4.       Return(  
  5.          <div>  
  6.             {this.props.CountNumber }<br/>  
  7.             <button onClick={this.props.handleClick}>Like</button>  
  8.          </div>  
  9.          )  
  10.       }  
  11.    }  
  12. Const enhancedCommentsCount = HOC(CommentsCount); // we created new component which uses the HOC Component.   
  13. Export default enhancedCommentsCount;  
App.js
  1. Function App(){  
  2.    Return(  
  3.       <div>  
  4.          < enhancedLikesCount />  
  5.          < enhancedCommentsCount />  
  6.       </div>  
  7.    )  
  8. }  
IN the above code we have removed the constructor and operation logic (because we used that in HOC, can access those using props) and assigned this component to the HOC component.
 
That’s it, now the both components will behave as like old, but the operation logic is from HOC. Now it’ll reduce your code, time and performance.
 
I hope this will be useful. Thank you for reading!.