paint-brush
Why you should keep your react components pure by using HOCsby@DjamelH
3,112 reads
3,112 reads

Why you should keep your react components pure by using HOCs

by Djamel HassaineApril 24th, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Building front-end apps these days involves a lot of complexity. Gone are the days when some html sprinkled with a bit of jQuery would cut it. Today we want responsive, rich, dynamic single page apps (<strong>SPA</strong>) that can work on a vast array of devices and browsers — this is no easy task. Luckily we have powerful frameworks and libraries that can help us. In this article I show how decomposing state from the presentational layer can both reduce complexity and promote code re-use with some <a href="https://facebook.github.io/react/" target="_blank">React</a> examples— a win-win situation helping to tame the challenges of developing SPAs. Although I’m using React, the lessons are universal and can apply to any <a href="https://hackernoon.com/tagged/framework" target="_blank">framework</a>.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Why you should keep your react components pure by using HOCs
Djamel Hassaine HackerNoon profile picture

Building front-end apps these days involves a lot of complexity. Gone are the days when some html sprinkled with a bit of jQuery would cut it. Today we want responsive, rich, dynamic single page apps (SPA) that can work on a vast array of devices and browsers — this is no easy task. Luckily we have powerful frameworks and libraries that can help us. In this article I show how decomposing state from the presentational layer can both reduce complexity and promote code re-use with some React examples— a win-win situation helping to tame the challenges of developing SPAs. Although I’m using React, the lessons are universal and can apply to any framework.

Warning, below lies plenty of code

Consider a simple toggle React component which can show either ‘on’ or ‘off’:

We’re using some ES7 syntax here, but basically the component can render two different elements and switches state by the user clicking on it. Being responsible developers, we can test it with the following (and if we were being really responsible, we would have written these tests first 😋):

So far so simple… apart from being a bit sparse on the number of tests — never mind. But let’s say we have another component similar in nature but different enough to warrant its own code, e.g. an info component that can show or hide a message:

The component has different properties and displays a different set of elements; however the tests end up being very similar because fundamentally the components are the same: a conditional rendering on a single boolean state variable.

In each component, a significant proportion of code and tests is related to managing the state. Imagine repeating this process across a large codebase — that might get a bit tedious. So what can we do?

Introducing higher order components, aka HOCs

Image courtesy of serenityatsummit

What’s a HOC!?

A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.

Concretely, a higher-order component is a function that takes a component and returns a new component. https://facebook.github.io/react/docs/higher-order-components.html

The following code shows a HOC that can wrap any component with an on/off boolean state a click handler to toggle the flag:

Notice that it is just a function with a single parameter WrappedComponent (the react component to add the extra functionality to) and it returns a new react component; this component is responsible for rendering the original component but decorated with the boolean on property and the toggle function to manage the state; it also passes through any other properties you want.

The awesome thing about HOCs is that because they are simply functions, we can compose multiple HOCs together to add potentially infinite functionality. We can create simple generic and well tested HOCs and end up with complex and powerfully composed components.

Let’s not forget the tests for our HOC:

And now on to our pure components

Image courtesy of eastcottvets

A pure function is a function that, given the same input, will always return the same output and does not have any observable side effect. https://drboolean.gitbooks.io/mostly-adequate-guide/ch3.html

Look how beautiful our Toggle component is now. We can also use destructuring on the component’s properties (Toggle = ({on, toggle}) => .. ) which makes it very declarative and obvious how to use the component, i.e. it needs two parameters: on and toggle; if we check the propTypes object, we can also see that they are a boolean and function respectively. If you would like to learn more about destructuring, check out my article JAVASCRIPT ES6 DESTRUCTURING AND A FEW USEFUL TRICKS

We then wrap our pure component with the on state and toggle functionality using our withState HOC.

Our tests:

Our tests have change now: we only care if the toggle function is called when the component is clicked; we trust the actual state manipulation has been tested already — and it has!

Let’s see how the Info component is re-written to use the withState HOC:

Lovely!

And the tests:

Pretty straight forward like the Toggle component’s tests.

Conclusion

Hopefully you’ve seen how we can delegate some state to HOCs which simplifies our React components by allowing us to develop with lovely pure functions. As we may end up reusing our HOC extensively, this encourages us to invest the time and energy in writing high quality generic code and covering the code thoroughly with unit tests. For example, the simple withState HOC presented in this article should probably be refactored to use a function for setting state instead of directly using an object (see this article for more info). For our simple use-cases above it won’t cause any problems, but if its to be a solid reusable HOC, we really should.

If you would like to experiment with the code presented in this article, feel free to clone/fork my repo.

If you found this article useful/inspiring tap the 💚 so others can enjoy it, too.

Thanks for your time! Follow me on Twitter and LinkedIn.

P.S. if you are interesting in building complex apps, you might enjoy my article Architecture of a SaaS (sentinurl.com) for some high level architecting advice.