A Deep Dive into the React HOC (2)

In the previous chapter, we learned what HOF (Higher Order Function) and HOC (Higher Order Component) are about and how they could be applied. Still, you may not fully understand the actual application of HOC for a project.

In this document, let’s create more practical examples of HOC and delve into problems that may occur during the process as well as ways to solve them.

Basic Exercise: Trace Window Scrolls

Let’s start with a simple exercise. I want to create a component that shows the location of windows scroll every time it changes. To this end, an event handler of scroll of window must be registered and unregistered, each when the component is mounted and unmounted.

It needs some effort, but the implementation is simple requiring not such long codes. However, what if there are many components that need to react whenever a window scroll is relocated? Then, the logic of a same format must be duplicated at each component. This is so-called Cross-Cutting Concerns, and with HOC, code duplication can be efficiently removed.

Now, let’s make use of the above component code to create HOC. To start with, we need to look back on how HOC is defined.

HOC is a function that receives a component as parameter and returns a new component. In other words, our first job is to create a function.

The newly-returned component class is the same as WindowScrollTracker, created at the beginning, except the render method. In the render method, render WrappedComponent, which is the received parameter of the withWindowScroll function, while sending down x, y information managed by state as props.

Note that as WrappedComponent may have its own props, other than x,y, all props should be delivered.

Then, let’s redefine WindowSizeTracker, created at the beginning, by using the withWindowScroll HOC function. Remove all, except the render method from the existing logic, and call HOC to define a new component. Now, in the render method, props received from withWindowScroll, instead of this.state are available.

The HOC can be used by any component requiring the application of changed window scroll locations. For example, for a component that shows “Top” only when the scroll is located on top, the implementation can be simple as below:

Customizing HOC 1: Add Parameters

Let’s develop further on the exercise. What if a component using withWindowScroll wants to throttle scroll events? As each component may want different wait value, additional parameters must be received for processing. Then, let’s modify the code to receive the second parameter as an object, so as to receive custom value as wanted.

As a result, each component now can use their wanted throttle values as below:

Customizing HOC 2: Props Mapper

Components that are returned through the withWindowScroll function are injected with x, y as props. However, what about using a nested HOC that injects props in the same name? For example, let’s assume the use of the HOC named withMousePosition, which injects the mouse location in the name of x, y, as below.

In this case, x, y injected through withWindowScroll shall be overrun by another x, y injected through withMousePosition. One of the commonly-mentioned disadvantages of HOC is that props name of nested HOC may be conflicted, and it can be simply resolved by providing a mapper function.

To better understand it, think of mapStateToProps which is used in the connect function of the familiar React-Redux Library. One of the functions of the connect function is to inject state stored at a store to a component. Here, by making use of the mapStateToProps function, you can select only the state that a component wants and also specify the name of props.

As such, MyComponent gets props named userName and userScore only, instead of the entire state. Likewise, when calling HOC functions, by delivering the mapper function that returns the props you want injection for as objects, conflicts of name can be resolved.

Now, let’s modify the withWindowScroll function more, so as to support the mapProps function.

By using mapProps, completely different data can be delivered to props through calculation. For instance, in the case of TopStatus implemented earlier, all is required is to know whether the scroll-Y is 0 or not, and mapProps can help to implement more efficiently as below:

In the above, you can find TopStatus is PureComponent. Indeed, all we need is to check whether the scroll-Y of TopStatus is 0 or not, but in the existing implementation, new props are received every time scroll value changes, creating unnecessary rendering constantly. However, the changed code receives props only when the isScrollOnTop value changes, so as to prevent unnecessary rendering by using PureComponent.

Nesting HOC — Compose

Let’s look through again how withMousePosition and withWindowScroll are nested among codes used in the above:

As function calls and each parameter values are nested, it’s not easy to get it clearly. If HOCs are nested even more, you’ll find harder time to recognize codes.

To resolve this issue, React recommends a convention for HOC. Convention is similar to the connect function of React-Redux. Like below, the connect function refers to a function that returns HOC, not HOC itself.

In other words, allow the HOC function to receive only one parameter (component) at all times, by providing another function to this end. Changing API of withWindowScroll to fit for this format should result in the following:

When all HOCs receive only one parameter, it will end up in a format like Component => Component, helping to process nested HOCs more elegantly by using libraries, like compose of Redux or flow of Lodash. For instance, let’s assume there is a total of three HOCs to nest, including the connect function of React-Redux in our previous exercise. In this case, using the compose function helps to write the code as simply as follows:

Supporting this with the withWindowScroll function is not difficult: wrap the logic which returned existing components with the function once again.

Debugging- Display Name

I have one last thing to point out: writing a code like in the above example may result in a component returned by actual HOC without a name, which is cited as one of the disadvantages of HOC. This, through React developer tool, will look like this:

As such, names like _class3, _class2 do not show precise information on components for debugging. That’s why React is supposed to specify a displayName for components returned by HOC, according to its conventions.

The above figure shows that a component returned by the connect function of React-Redux is named with Connect(_class3).The convention stipulates the HOC name start with an upper case letter followed by displayName of the component within parenthesis. To apply it to the withWindowScroll function, write as follows:

As a consequence, codes are more complicated, but following conventions will surely help for easy debugging in the future. With such modification, the developer tool will display the following:


In Chapter 2, we touched upon simple HOCs and some methods and conventions, with more functions added. If you’ve learned well enough, you’ll find no problems in making use of HOC in actual projects.

I mainly focused on the usage and good points of HOC but it has disadvantages as well. For example, to test nested HOC with shallow rendering or use static members of WrappedComponent, additional codes are required, and it is not easy to receive necessary information from WrappedComponent and process it for a rendering.

This has been translated into more interest in Render Props, and the official website of React, starting this year, has also added Advanced Guides of Render Props. Its popularity has grown more, even as the Context API on its latest 16.3.0 version adopts Render Props. If you’re interested in more details, I recommend you read Use a Render Prop! , which is a famous article on Render Props.

Nevertheless, I don’t personally consider Render Props as a better concept than HOC, because each of them contains pros and cons (and let me elaborate on them, in my future articles). If properly used, HOC can be made into a more flexible structure through the composition of components, while duplicated codes of React are completely removed.

Originally posted at Toast Meetup written by DongWoo Kim.

JavaScript UI Library Open Source by http://ui.toast.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store