Getting started with Higher Order Components and Recompose

Higher order components (HOCs) are functions that take a component and return another. The returned component is altered, typically, to add a feature or enrich it with more functionality than it originally contained.

I always knew that higher order components were a thing and important to know but no one could convince me why they were important. Therefore I wrote this post to explain in my own words:

why we need them by way of a quick introduction to imperative vs declarative programming

how HOCs can make you a better programmer even if you don’t use them directly e.g. Higher order functions (HOFs)

using an example of data loading HOC, how Recompose can take them to the next level

Imperative vs Declarative Programming

Declarative programming is the CORE philosophy behind HOCs. Getting straight to the point, we yearn for writing code that looks less like code. Why? As your code base gets larger, more complicated and used by more than one person or team I found I ended up reading more and more code instead of getting on with implementing a feature or fixing a feature. When someone created a feature, I’d still have to stare at their code to understand exactly what it did unless they explained it to me or had some reasonable documentation (but even that wasn’t always enough). So I started using HOCs without even understanding their benefits and I found that I read less code and got more done. I wasn’t writing any less or more code, I just spent less time staring at code. Hmmmmmm…… What I was really experiencing was the shift from imperative to declarative programming.

Imperative Programming is how we traditionally write code. It looks like code and smells like code. It uses things like iterators, variables and other constructs to explain how to get what we want

Declarative Programming is like writing a story or specifying a series of phrases to describe our intentions. We use pre-defined functions to explain what we want

Did that feel a bit overwhelming at first? Did you have to stare at the code for a while…? Right, so in the above code I’m iterating over a bunch of movies and getting a list of those with a rating of 5 and genre of ‘Sci-fi’. And by the way I only want the id and title of each movie.

Declarative Programming

OK now look at the following code that’s doing the same thing but in a declarative way:

we first passed our movies to getMoviesWithRatingOf5. The resultant movies were then passed to the getSciFiMovies and finally getMovieTitles iterated over the resultant movies and returned only their id and title.

Provided we have a bunch of functions like getMoviesWithRatingOf5, we just have to combine them in the right order to get what we want. We are describing/explaining what we want.

Higher Order Functions

So far I’ve shown how writing in a declarative way makes our code easier to read and write. But I still haven’t associated it with HOCs. Believe it or not, we just used higher order functions or (HOFs) in that last example called filter and map. These do exactly the same as HOCs but with functions instead of components. Like I said earlier, knowing about HOCs will make you a better programmer. If you understand the core patterns of HOCs you can make higher order anythings resulting in more readable and maintainable code! Let’s take a very brief look at HOFs because you’re going to be a lot more familiar with them than you think and they are therefore an excellent segue into HOCs…

“Higher order functions are functions that take a function and return a function”

E.g. the map HOF takes a function and returns another function that iterates over a collection applying that specified function against each collection item. In our example above we iterated over a collection of movies and used the map function in ‘getMovieTitles’ to only return id and title for each movie. This is an example of what the implementation of the map HOC might look like (just to show there’s no smoke and mirrors):

Higher Order Components

Higher order components are essentially the same thing but with components.

“Higher order components are functions that take a component and return a component”

Let’s look at a very common scenario in plain Javascript (using React) where we want to display some person’s details. Their details have to be loaded from a backend service so we need to show a loading animation while that person waits so they know the application is still working.

Here is our function for asynchronously fetching our person’s details from a backend service (yes you got me… it’s a setTimeout function to simulate a back end call to a non-existent service which is good enough for this example).

You can also examine and run the code used throughout the post from this code sandbox.

Great so let’s break up that HOC and look at it in more detail…

Part 1 – Define the HOC

import React from ‘react’;
import ‘./WithLoadingSpinner.css’;

export const WithLoadingSpinner = fetchData => WrappedComponent => {

After importing React and some CSS for the spinner animation we create a HOC component called ‘WithLoadingSpinner’. WithLoadingSpinner is a function that takes a parameter called ‘fetchData’ (the function that fetches data). WithLoadingSpinner is now a function that returns another function that takes a parameter called ‘WrappedComponent’ (the ‘MyDetails’ component that will display data from the fetchData function).

Tip – Just like numbers, strings, booleans, etc., functions are values. That means that you can pass functions around like any other data. You can pass a function as an argument to another function e.g the function that returns a function that returns ‘some data’

Here we return an ‘anonymous React component’ whose initial state is that of ‘loading’. The render function will display the spinner while we are in a state of ‘loading’. After the spinner is mounted, ‘componentDidMount’ will call ‘fetchData’ and once data is retrieved, the component’s loading state will end, the component will re-render and display the ‘WrappedComponent’ or ‘MyDetails’ component with the data passed to it as properties. Yay!

Higher Order Components with Recompose

The above HOC was looking rather complicated…. let’s see what it looks like when we re-write the WithLoadingSpinner HOC using Recompose

withData HOC – This little guy will take our MyDetails component and add/modify its lifecycle function componentDidMount to include code to call ‘fetchData’ just like in the previous example

withSpinnerWhileLoading HOC

withData uses Recompose’s lifecycle HOC to add life cycle behaviour. Any state changes made in a lifecycle method, by using setState, will be propagated to the wrapped component as properties. In this case withSpinnerWhileLoading receives the properties e.g. { loading: false, …data }

Recompose’s branch test function takes (in this example) two arguments. The first argument is a test which checks if the ‘loading’ component property is true or false and the second argument is a component to return if the test function resolves true. When ‘loading’ is true we use Recompose’s renderComponent which takes a loading spinner component and returns a HOC version of it which is returned instead of ‘WrappedComponent’. When ‘loading’ is false however, ‘WrappedComponent’ is returned instead

Testing Higher Order Components

Testing HOCs is no different to testing normal components. You use the HOC to take a mock/dummy component into an enhanced component and then test that enhanced component using Enzyme e.g.