Higher Order Components (HOC) in React
A HOC is a pattern where a function takes component as an argument and returns a new component.
const NewComponent=heigherOrderComponent(originalComponent)
basically HOC adds additional data to original component that can be called an enhanced component. a HOC is used to provide a common functionality across the components.
Lest Understand this using an example
// create two componetns where the count increases when button is clicked
// and one where when hoverd on it
import { useState } from "react";
export default function HoverIncrease() {
const [counter,setCounter]=useState(0)
return (
<div>
<button onMouseOver={()=>setCounter(counter+1)}>Increment</button>
<p> value on HoverIncrease: {counter}</p>
</div>
);
}
import { useState } from "react";
export default function ClickIncrease() {
const [counter,setCounter]=useState(0)
return (
<div >
<button onCLick={()=>setCounter(counter+1)}>Increment</button>
<p>Value of counter on ClickIncrease: {counter}</p>
</div>
);
}
As from above code we can see when the components are called both have a counter logic, which is common and can be shared across them , by creating a HOC.
import { useState } from "react";
export default const UpdatedComponent = (OriginalComponent) => {
return (function NewComponent(props) {
const [counter,setCounter]=useState(0)
return (
<OriginalComponent
counter={counter}
incrementCounter={() => setCounter((counter) => counter + 1)}
{...props}
/>
));
Note: as you can see props is passed down it is the most common mistakes as your original component might be receiving other props also than needs to be there in the enhanced component also.
Inside other two component we would wrap them inside our HOC
import { useState } from "react";
import UpdatedComponent from "./UpdatedComponent";
function HoverIncrease(props) {
const { counter, incrementCounter } = props;
return (
<div>
<button onMouseOver={() => incrementCounter()}>Increment</button>
<p> value on HoverIncrease: {counter}</p>
</div>
);
}
export default withCounter(HoverIncrease);
import { useState } from "react";
import UpdatedComponent from "./UpdatedComponent";
function ClickIncrease(props) {
const { counter, incrementCounter } = props;
return (
<div>
<button onClick={() => incrementCounter()}>Increment</button>
<p> value on HoverIncrease: {counter}</p>
</div>
);
}
export default withCounter(ClickIncrease);
Also , the HOC can accept other parameters as an argument, here modified HOC which accepts parameters also
import { useState } from "react";
export default const UpdatedComponent = (OriginalComponent,incrementBy) => {
return function NewComponent(props) {
const [counter,setCounter]=useState(0)
return (
<OriginalComponent
counter={counter}
incrementCounter={() => setCounter((counter) => counter + incrementBy)}
{...props}
/>
);
}
import { useState } from "react";
import UpdatedComponent from "./UpdatedComponent";
function ClickIncrease(props) {
const { counter, incrementCounter} = props;
return (
<div>
<button onClick={() => incrementCounter()}>Increment</button>
<p> value on HoverIncrease: {counter}</p>
</div>
);
}
export default withCounter(ClickIncrease,10);
As you can see, a common functionality is shared across the component while the initial components are enhanced.If you encountered any difficulties in this article, my suggestion to you is to deconstruct and play with the code samples above. This will help you understand the concept better.
If you’d like to be in the know, subscribe, clap, like and share. Cheers!