Never miss an article about web development, JavaScript and self-growth.

Take Part

A gentle Introduction to React's Higher Order Components

Another fitting headline for the article could be: learn Higher Order Components with Conditional Rendering in React.

Higher order components, or known under the abbreviation HOCs, are often a difficult to grasp pattern in React (next to the render props pattern). These components can be used for multiple use cases. I want to pick out one use case, the conditional rendering with higher-order components, to give you two outcomes from this article as a reader.

First, it should teach you about React’s higher-order components with the use case of conditional rendering. Keep in mind, that altering the look of a component with a higher-order component, specifically in the context of conditional rendering, is only one of several use cases to use HOCs. For instance, you could use them to opt-in local state or to alter props as well.

Second, even though you might already know HOCs, the article goes a bit further by composing higher-order components in React with the library recompose and by applying functional programming principles. You will get to know how to use higher-order components in an elegant way.

In order to teach React higher-order components, the article focuses on the use case of conditional rendering. A conditional rendering in React can be applied in multiple ways. You can use if-else statements, the ternary operator or the logical && operator. You can read more about the different ways in another article about conditional renderings in React. If you are not familiar with conditional rendering in React, you could read the article first.

A Growing React Component

We will start with a problem in React where higher-order components could be used as solution. Let’s assume our application has a TodoList component.

In a real world application that’s not sufficient most of the time. You have to bother with so much more. Usually you would put the so much more related things outside of your TodoList in the parent component. But to keep the example and learning experience concise, I will place every so much more edge case in the TodoList component.

What are these edge cases I am speaking about?

First, what happens when your todos are null? You would apply a conditional rendering to opt-out earlier from your rendering.

Third, since the todos arrive asynchronously from your backend, you want to show a loading indicator in case the todos are still in a pending request. You would get one more property, such as ‘isLoadingTodos’, to know about the loading state.

Okay. I don’t want to make this more complex as it is. But you get the idea that a lot of edge cases for conditional renderings can add up in a simple component. Higher order components can solves this issue. They can be used to shield away these edge cases as reusable functionalities. Thus the TodoList has not to worry about it anymore. Let’s enter the concept of React’s higher-order components to deal with it.

Entering React's Higher Order Components

Higher order components usually take a component and optional arguments as input and return an enhanced component of the input component. In our example, the goal would be to shield away specifically all the conditional rendering edge cases from the TodoList component.

Let’s remove the first case from the TodoList where the todos are null.

Now let’s implement our first higher-order component in React to take ownership of this functionality. Higher order components can come with the naming prefix with, but it is not mandatory. In the end, it makes it easier to distinguish a React component from a React higher-order component.

Basically the withTodosNull function is a higher order function. It takes an input and returns another function. Since we use it in the context of React, we can call it a higher-order component. Because it takes a Component as input and returns another Component. We don’t return another Component yet, but we will do later on. In this case it will return a functional stateless component, but it could return a ES6 class component as well. Depending on your use case you can use different component types. Yet a functional stateless component is sufficient for the sake of conditional rendering. When you would need access to this.state or React lifecycle methods, you could return an ES6 class component.

First, there is a conditional rendering with the ternary operator. The higher-order component decides whether it shows nothing or the input component based on the condition. If the todos are null, it shows nothing. If the todos are not null, it shows the input component.

Second, all the props are passed - further down the component tree - to the input component. For instance, if you would use the withTodosNull HOC to enhance the TodoList, the latter would get all the props passed through the HOC as input with the JavaScript spread operator.

All the function and return statements make it hard to work with higher-order components. You can use JavaScript ES6 arrow functions to make it concise again.

As a side note, to avoid confusion: In a JavaScript ES6 arrow function you can omit the curly braces. You transform the block body to a concise body. In a concise body you can omit the return statement because it will implicitly return.

There is only one nitpick. The withLoadingIndicator passes all the props to the input component. Even though the input component is not interested in the isLoadingTodos. You can use the JavaScript ES6 rest destructuring to split up the props.

The order to apply the higher-order components should be the same as in the previous TodoList with all implemented conditional renderings. Otherwise, like in the basic TodoList component that had all the conditional renderings, you would run into bugs because of an length check on an null todos object.

Isn’t that great? We shielded away all the conditional renderings and the TodoList component only bothers to render todos. Now you know how to use higher-order components. As I said, the article taught HOCs leveraging conditional rendering. But you can use them for various use cases.

But it is kinda tedious to wrap all the components by hand into each other.

Still, it is not readable. React embraces functional programming, so why are we not using these principles?

Entering Recompose in React

The little higher-order component library recompose has a lot built-in higher-order components that you can re-use. You should definitely check them out after you have read this article. However, it comes with a neat functionality called compose that allows you to return one function composed out of multiple functions. These multiple functions could be all of our conditional rendering HOCs. And that’s how you use it:

That’s convenient, isn’t it? You can use compose to pass your input component through all higher-order component functions. The input components gets an enhanced version of the component in each function.

After all, higher-order components themselves are reusable. By composing these components into each other, you get a lot of permutations of component enhancements.

Reusability with abstracted Higher Order Components

The higher-order components of the last section were pretty specific. Each of them had a specific use case matching the requirements of the TodoList component. You wouldn’t be able to use them in another context, to be more specific, in another component with a different props structure. Thinking about the long term investment in an application, you could abstract these higher-order components to make them reusable by other components too.

As I mentioned, higher-order components take an input component and an optional payload. These optional payloads are often used for configuration.

Let’s give the withTodosNull an optional payload. The payload is a function that returns true or false to decide the conditional rendering.

The name of the higher-order component is misleading now. The HOC is not aware anymore of the props data structure nor is it aware of the todos at all. You could name it withCondition, because it takes a function that returns true or false.

The withCondition HOC enables you to re-use it everywhere for a conditional rendering that returns the input component or nothing. It is independent of the input component, independent of the condition and independent of the props structure.

That’s not going to work. The function signature of withCondition has two arguments: the input component and the optional payload that is the conditional function. But composing works by passing only one value from function to function.

Here is the catch in functional programming. You will often pass only one argument, that’s why currying exists. However, you don’t need to bother with a curry function now. So instead of using two arguments in the withCondition higher-order component, you can use another higher order function.

That’s a powerful abstraction, isn’t it? You can use the first higher order function to pass the optional payload and return the higher-order component that is used in the composition.

Maybe and Either Higher Order Components

You can use the naming conventions and principles of functional programming (FP) to name your abstracted higher-order components properly. Developers who are familiar with FP will know the use case of the HOC by seeing its name.

The component returns nothing or the input component. Such a type, nothing or value, is called Maybe (or Option) in functional programming. After knowing this, you could call the higher-order component withMaybe. Even though the HOC is not an explicit type, it would use the naming convention of FP to make it simple to understand.

What about the other two HOCs? They are not abstracted yet. They are different from the withMaybe higher-order component, because they return either the input component or another element. The Either type in FP defines these two differing values. In addition, similar to the withMaybe, the withEither could take as additional payload a component that should be shown if the condition doesn’t match.

If you are curious about how recompose makes stateless components stateful, you can checkout this article: React State without a Class.

I hope the article helped you to learn higher-order components in the context of conditional rendering. In addition, I hope that it gave you inspiration on how you can use abstraction and functional programming with higher-order components.