Higher Order Components.
Published: 2022-04-16 23:52:45

Have you ever used React and felt compelled to duplicate the same logic across numerous components? I'm sure you're wondering if there's a method to reuse logic across multiple components in React without rewriting it. Yes, there is! Higher-Order Components (HOCs). HOCs offer an advanced approach to dealing with such cross-cutting concerns.
In this tutorial, you'll explore HOCs in-depth, why there’s a need for HOCs, when to use the pattern, what's a HOC and finally, create a simple React app using HOCs.

## Why’s there a need for a HOC?

Imagine a client approached you, then asked you to create an App with a button indicating the number of times it’s clicked. You create a component called `ClickCounter`, where you store the `button` and its counter functionality. Export, then import and render it in the `App` component.

[![1.png](https://i.postimg.cc/brTBRcg8/1.png)](https://postimg.cc/p5mC2S31)
After some time, the client comes back and asks you to add a heading indicating the number of times it’s hovered over. Basically a `ClickCounter` with click functionality replaced by hover functionality. You create a new component called `HoverCounter` which stores the heading and counter functionality. Export, then import and render it in the `App` component under `ClickCounter`.

[![2.png](https://i.postimg.cc/vBShzrxq/2.png)](https://postimg.cc/tZWFRV5W)
Again, the client comes back and asks you to add an input that counts the number of keypresses in the project. For Example A key up in an input element to increment a counter value and display it. You can of course implement it the same way you implemented the counter in `ClickCounter` and `HoverCounter`. But realize you are duplicating code and not really reusing the counter functionality. So if 10 different components needed the counter functionality you would write the same code over and over again.
So how can you really reuse the counter functionality?
The immediate thought is to lift `state` from the parent component and pass it down the handler as a `prop`. Define the counter functionality in `App` component, provide the state and the handler as props to `ClickCounter` and `HoverCounter`. Since you only have two components, it would work. But imagine a scenario where the counter components are scattered across the React App. Lifting the `state` would definitely not be the correct solution. So there’s a need to share common functionality among components without repeating code. That’s where the concept of HOCs comes in.

## So when do you really use the HOC pattern?

Basically HOCs allow you to share common functionality between components.

## What’s a HOC?

Basically, a HOC is a pattern where a function takes a component as an argument and returns a new component.

[![3.png](https://i.postimg.cc/25WLJnt9/3.png)](https://postimg.cc/jWsjnnty)
A HOC adds additional data or functionality to the component. The new component can be referred to an `EnhancedComponent`.

[![4.png](https://i.postimg.cc/pLhmhDPV/4.png)](https://postimg.cc/pmvW3593)
From a non-technical point of view

[![5.png](https://i.postimg.cc/CLHRjFqX/5.png)](https://postimg.cc/bsrYPfL9)

`withSuit` is the function that will enhance `TonyStark` and return `IronMan` which is the `EnhancedComponent`.
From React's point of view we have function which accepts `OriginalComponent` adds functionality and returns the `EnhancedComponent`.
Consider implementing a basic HOC then implement it with the counter example-
Create a new file called `withCounter.js` within the components folder.

### Consider this example-

[![6.png](https://i.postimg.cc/QNcQyZ7k/6.png)](https://postimg.cc/G9hT4NqH)
In the above example, the `UpdatedComponent` is a function that takes a component called `OriginalComponent` as an argument. You have created a new component called `NewComponent` which returns the `OriginalComponent` with a name `prop` from its render function. While this actually adds no functionality, it depicts the common pattern that every HOC will follow.

## Creating a simple React app using HOCs.

Apply the HOC pattern to the `ClickCounter` and `HoverCounter`. In `ClickCounter` you will import `UpdatedComponent` from `withCounter` while exporting it will call the `UpdatedComponent` function passing in the `ClickCounter` component. You’ll do the same for `HoverCounter`. Instead of exporting the `ClickCounter` or `HoverCounter` component you export the `UpdatedComponent`. The HOC in addition to being the `ClickCounter` or `HoverCounter`.
To modify your HOC so as to allow the counter functionality to be shared among components. You will cut the `constructor `and `incrementCount` function from `ClickCounter` into the HOC. Since it’s the common functionality we want to share, remove the same code from `HoverCounter`.
You need to pass down the `state` and `incrementCount` method as `props` so that the `OriginalComponent` can make use of that functionality.

<!--  -->

[![7.png](https://i.postimg.cc/MTvH3m2N/7.png)](https://postimg.cc/wyY97JBQ)

In both `ClickCounter` and `HoverCounter` you will destructure `count` and `incrementCount` from `this.props`. If you look at the project, it functions as perfectly but the difference now is that you are reusing code instead of duplicating it.

[![8.png](https://i.postimg.cc/8PwQV3vx/8.png)](https://postimg.cc/6y71rMYh)

[![9.png](https://i.postimg.cc/CKBWkx2V/9.png)](https://postimg.cc/9428jCVx)

Now, you can change the naming convention. The component and functions you have used are different from what you typically see. So change them. The function and file name is usually the same, it indicates the functionality being added to the components. The `OriginalComponent` is usually referred to as the `WrappedComponent`. The `NewComponent` is usually the same as the function name, but in `Pascal case`.

[![10.png](https://i.postimg.cc/1X8Wz2xB/10.png)](https://postimg.cc/Pvkb365v)

You’ll make the same changes to the naming convention while importing and exporting the HOC in the `ClickCounter` and `HoverCounter`.

[![11.png](https://i.postimg.cc/Rhp55spc/11.png)](https://postimg.cc/1VFYDHQt)

[![12.png](https://i.postimg.cc/8CR2PPnk/12.png)](https://postimg.cc/d70H5vYg)

### Before winding up consider these two things:

- Passing down the `props`.
  In `App` component you will pass a name `prop` in the `ClickCounter` component.

  [![13.png](https://i.postimg.cc/vBK9D9B5/13.png)](https://postimg.cc/9RGznDyf)

  Render the name `prop` in `ClickCounter`.

  [![14.png](https://i.postimg.cc/GpPPqzQK/14.png)](https://postimg.cc/nszQL4N9)

  If you go to the browser the name value is not displayed. This is a common mistake when starting off with HOCs. The problem here is that when you specified `props` on the `ClickCounter` component, the props are passed down to the HOC and not `ClickCounter`. If you log out the name from in the HOC in the `render` method. You can see you do have the name `prop` for `ClickCounter` and undefined for `HoverCounter`.

  [![15.png](https://i.postimg.cc/N0B0tx65/15.png)](https://postimg.cc/VJZwBnH8)

  To fix this issue you need to pass down the remaining `props` to the `WrappedComponent` using the spread operator. Basically the HOC adds two `props` to the `App` component then passes down the remaining specified `props`.

  [![16.png](https://i.postimg.cc/8k2J3M0r/16.png)](https://postimg.cc/23xSLbmz)

- Passing parameters to the HOC function.
  In the HOC instead of incrementing the value by 1. You would want to increment it by different numbers for both `Counter` components. You can do that by passing a parameter to the HOC function.
  First `WrappedComponent` and second `incrementNumber`. You will now increment the `incrementCount` by the `incrementNumber` parameter.

  [![with-Counter.png](https://i.postimg.cc/9XtzZ8df/with-Counter.png)](https://postimg.cc/fkywhvg4)

  In `ClickCounter` you will add a second argument 5 and `HoverCounter` You will add 10.

  [![click-Counter.png](https://i.postimg.cc/rsCdpgJK/click-Counter.png)](https://postimg.cc/rRsyn17k)

## Conclusion
Congratulations! 🚀 You’ve reused common functionality within components in your application. Following the methodology in this tutorial can reduce errors caused by duplicating code. I hope you enjoyed this tutorial!