Higher Order Components in React.
Tags: react, webdev, beginners
Published: 2020-11-23 15:40:14

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6vvu1bc0jpmqniqz27w2.jpg)

Image by <a href="https://pixabay.com/users/pieonane-6778364/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=4509607">pieonane</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=4509607">Pixabay</a>

#Table of contents

1. [Higher Order Functions](#hof)
2. [Higher Order Components in React](#hoc)
3.  [Things to take note of while using HOC](#note)
4. [Conclusion](#conclusion)
5. [References](#references)

In this brief article, I will introduce you to `Higher Order Components` in react, sometimes written as `HOC` in brief.


## Higher Order Function <a name="hof"> </a>

For us to understand HOC in react, it is important to understand Higher Order Functions in javascript. According to [The eloquent javascript](https://eloquentjavascript.net/05_higher_order.html), functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions. In javascript, functions are first class citizens. This means a function can be passed as argument to another function, it can be returned from another function and can also be assigned to  a variable. In javascript, there a number of builtin higher order functions. The most common ones are the `Array` methods below:

- `map`
- `forEach`
- `filter`
- `reduce`

In the example below, I have implemented a function which is used for raising a number to a given power. It is a higher order function because it returns a function.

```js
const power = (power) => {
  return (base) => {
    return base ** power;
  };
};

const square = power(2);
const cubed = power(3);
console.log(square(100)); // 10000
console.log(cubed(100)); // 1000000

```
Essentially, higher order functions are regular functions that do one or both of the following.

- Takes one or more functions as arguments
- Returns a function

## Higher Order Components(HOC) in React <a name="hoc"> </a>

A higher-order component, in react, is a function which takes a component as an argument and returns another component. According to the [react documentation](https://reactjs.org/docs/higher-order-components.html),

> A higher-order component returns a new component after performing some kind of operation. For example,
> ```js
const EnhancedComponent = higherOrderComponent(WrappedComponent);
```
> Essentially a HOC transforms the input component into another component.

From the simple definition of a Higher Order Component above, you can immediately notice the similarities between Higher Order Functions such as `Array.prototype.map`, `Array.prototype.filter`, `Array.prototype.forEach` **et cetera** and Higher Order Components in React.

To illustrate what I am talking about, let me give a contrived example below. It is unlikely you will do this in a real app but it goes a long way in explaining what HOC is.
```js
import React from "react";

function HigherOrderComponent(Component) {
  return class extends React.Component {
    render() {
      return <Component {...this.props} />;
    }
  };
}

function SayHello(props) {
  return <p> Hello {props.name} </p>;
}
export default HigherOrderComponent(SayHello);
```
From the above, you can see that `HigherOrderComponent` takes `Component` as parameter. It then returns anonymous class component which renders the component passed as argument to `HigherOrderComponent`. It is worth pointing out that I have used an anonymous component but you can also name it to increase readability of your code. A component which has been named appropriately can give you an idea of what it does even without looking at its code. 

The above component is a HOC but it is such a contrived example that you are unlikely going to use or encounter it in real-world projects. One of the main reasons for using HOC is to add enhancements to the component with functions or data, none of which our component above implements.

One use case of a HOC is to display a loading indicator while fetching data from an API. Below, I have defined a HOC which displays the text `Fetching Photos...` if `this.props.isFetchingPhotos` is `true` otherwise it returns a new component which renders the component passed as argument to the HOC. Notice how the `props` have been passed on to `Component` from `Component {...this.props}`.

`withLoadingIndicator.js`
```js
import React from "react";

function withLoadingIndicator(Component) {
  class WithLoadingIndicator extends React.Component {
    render() {
      if (this.props.isFetchingPhotos === true) {
        return <p> Fetching Photos... </p>;
      }
      return <Component {...this.props} />;
    }
  }
  WithLoadingIndicator.displayName = `WithLoadingIndicator(${Component.displayName ||
    Component.name ||
    "Component"})`;
  return WithLoadingIndicator;
}
export default withLoadingIndicator;
```
The above HOC is imported in `App.js`. It is then invoked with `Photos` as argument. The returned component is then finally rendered inside `App.js`.

```js
import React, { useEffect, useState } from "react";
import Photos from "./Photos";
import withLoadingIndicator from "./withLoadingIndicator";
import "./style.css";
const url = "https://jsonplaceholder.typicode.com/photos";

const WithLoadingIndicator = withLoadingIndicator(Photos);

export default function App() {
  const [photos, setPhotos] = useState([]);
  const [isFetchingPhotos, setIsFetchingPhotos] = useState(false);
  const [hasError, setHaserror] = useState(false);
  useEffect(() => {
    async function fetchPhotos() {
      setIsFetchingPhotos(true);
      try {
        const response = await fetch(url);
        const photos = await response.json();
        if (Object.keys(photos).length === 0) {
          throw new Error("Something wrong has happend");
        }
        setPhotos(photos);
      } catch (error) {
        setHaserror(true);
      }
      setIsFetchingPhotos(false);
    }
    fetchPhotos();
  }, []);
  if (hasError === true) {
    return <p> An Error has occurred... </p>;
  }
  return (
    <div>
      <WithLoadingIndicator photos={photos} isFetchingPhotos={isFetchingPhotos} />
    </div>
  );
}

```
If you have ever used state management library  redux, most likely you have come across react-redux which is used for connecting your app to the redux store. The `connect` function returns another function which is a HOC. The component you want to connect to the redux store is  passed to the HOC returned by a call to `connect`.
```js
  const higherOrderComponent = connect(mapStateToProps, mapDispatchToProps);
  const EnhancedComponent = higherOrderComponent(Component);
```

## Things to take note of while using HOC <a name = "note"> </a>

Before you start using Higher Order Components, there are certain things you must always be cognizant of. These include:

#### Higher Order Components must be pure.

You shouldn't perform side effects in HOC and it shouldn't mutate the component passed to it. It should instead return a new component which renders the component passed as argument. A HOC is supposed to compose a component for code reuse. If  you are writing a HOC, avoid the temptation to mutate the component passed as argument. This is because once mutated, the input argument's new behaviour will also be reflected outside the enhanced component which makes it non reusable. Instead of mutation, HOCs should use composition, by wrapping the input component in a container component. It is expected HOCs pass on props that are unrelated to its specific concern. 

#### Naming convention for HOC

It is important to choose a display name that communicates to whoever is reading/debugging your code that the rendered component is a result of a call to a HOC. For example if your higher order component is `withLoadingIndicator` and input component is `Component` from the example I provided above, then the returned component can use the display name `withLoadingIndicator(Component)`. This will make it obvious that `higherOrderComponent(Component)` is a result of passing `Component` to 
`withLoadingIndicator`. This is illustrated in the example above.

#### Don't invoke HOC inside the render method.

In class components, the render method is invoked whenever a component renders. Invoking the HOC inside the render method like in the illustration below means every time the component is rendered, HOC is invoked. This will affect your app's performance. The best place to invoke the HOC is outside the component. If you are interested in creating a HOC dynamically, make use of the life cycle methods.
```js
render(){
  const EnhancedComponent = HOC(Component);
  return <EnhancedComponent />;
};
```
According to the react documentation,
> React uses component identity to determine whether it should update the existing subtree or throw it away and mount a new one. If the component returned from render is identical (===) to the component from the previous render, react recursively updates the subtree by diffing it with the new one. If they are not equal, the previous subtree is unmounted completely.

Since invoking the HOC inside the render method will lead to the creation of a new component on each render, this leads to the *unmounting* and remounting of the component which makes the component and all its descendants lose their state.

#### Static methods must be copied over

Sometimes it is important to declare static methods in class components. If you wrap a component on which a static method has been defined inside a HOC, the enhanced component doesn't have access to the static method. Since this is a brief introduction to HOC I won't describe how to go about solving this problem in this article,the react documentation prescribes solutions which you can read about [here](https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over).

#### `refs` are not passed

It is common practice to pass `props` which have been passed to the enhanced component to the wrapped component. However, this is not possible with `refs` because `refs` are not handled by React like ordinary props. The solution is to use `forwardRef` API. If you are not familiar with it, you can read about `forwardRef` in one of my earlier articles [What is `forwardingRef` and how do you use it?](https://dev.to/nibble/what-is-forwardingref-and-how-do-you-use-it-2bm6).


***

##Conclusion <a name="conclusion"> </a>

In this brief article about HOC, we learned about:
1. Higher Order Functions and how it is related to Higher Order Components.
2. Higher Order Components. What HOCs are, when it is necessary to use HOCs and things worth taking note of while using HOCs.

***
I am glad you have read this article till the end. If you find anything technically inaccurate, feel free to leave a comment below. If you find it useful, consider sharing it on social media or any other platform. Others might find it useful too.

##References <a name="references"> </a>

1. [React documentation](https://reactjs.org/docs/higher-order-components.html)
2. [Simple Explanation of Higher Order Components by Jakob Lind](https://blog.jakoblind.no/simple-explanation-of-higher-order-components-hoc/)