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 of 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 , created at the beginning, except the method. In the render method, render , which is the received parameter of the function, while sending down , information managed by as props.

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

Then, let’s redefine , created at the beginning, by using the HOC function. Remove all, except the method from the existing logic, and call HOC to define a new component. Now, in the method, props received from , instead of 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 wants to throttle scroll events? As each component may want different 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 function are injected with , 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 , which injects the mouse location in the name of , , as below.

In this case, , injected through shall be overrun by another , injected through . 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 which is used in the function of the familiar React-Redux Library. One of the functions of the function is to inject state stored at a store to a component. Here, by making use of the function, you can select only the state that a component wants and also specify the name of props.

As such, gets props named and 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 function more, so as to support the function.

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

In the above, you can find is PureComponent. Indeed, all we need is to check whether the scroll-Y of 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 value changes, so as to prevent unnecessary rendering by using PureComponent.

Nesting HOC — Compose

Let’s look through again how and 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 function of React-Redux. Like below, the 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 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 , 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 function of React-Redux in our previous exercise. In this case, using the function helps to write the code as simply as follows:

Supporting this with the 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 , do not show precise information on components for debugging. That’s why React is supposed to specify a for components returned by HOC, according to its conventions.

The above figure shows that a component returned by the function of React-Redux is named with .The convention stipulates the HOC name start with an upper case letter followed by of the component within parenthesis. To apply it to the 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:

Conclusion

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 , additional codes are required, and it is not easy to receive necessary information from 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