If you like listicles, you’ll like recompose

Abdul Nimeri
Jul 28, 2017 · 3 min read

I’m not that adventurous when it comes to my JS libraries. I often get dragged kicking and screaming into learning new things when I touch existing codebases. And my latest affliction –– recompose –– just looked nuts!

If you haven’t heard of it, recompose is a library full of handy, composable higher-order components. It looks weird at first, but I’m happy to say that I learned to appreciate recompose’s approach.


FP looked weird at first, too

Forget about recompose for a second. Let’s talk about some functional helpers: map, reduce and filter. Do you remember your first impressions with those? I do. “Ugh, why would I want to use those? My for loops work just fine.”

So the nice thing about using a functional helper like map is it provides you with information up front. For example, I might be looking at this piece of code:

const result = myArray.map(
// 20 lines of stuff here
...
...
);

Without reading the body, I already know that it’s transforming myArray into another list of the same length. If I’m hunting down a bug where there are some missing elements, I know I don’t have to read those 20 lines. Compare that with your standard for loop:

for (var i = 0; i < len; i++) {
...
}

For loops are the wild west. Anything could be happening in there. Side effects, transformations, filtering... We don’t know anything ahead of time. We have to read the body. When you have a large codebase, individual lines that you’re forced to read are a liability. Using informative constructs like map and filter when appropriate adds up and makes for a codebase that’s easier to navigate.

React Classes are like for loops

So, back to React-land. When I see a React class, a couple questions come to mind: does this class contain any state? Does it have any lifecycle methods? Does it cache state on the component instance? Anything else I should worry about? Unfortunately, it’s not super easy to glean info from a React class:

class Foo extends Component {
constructor() {
...
}
fooHelper() {
...
}
componentDidMount() {
...
}
render() {
...
}
}

Without reading the body, I can’t find out what state it carries, and I can’t find out additional member variables (lifecycle methods are easy to spot at least!).

And this is where recompose comes in. In recompose, a component will look like this:

const Foo = (props) => 
<div>
...
</div>
const FooContainer = compose(
withState('bar', 'setBar'),
lifecycle({
componentDidMount() { ... },
}),

withHandlers({
fooHelper: props => () => { ... },
})
getContext(...),
)(Foo)

And voila! Recompose turns your React class from a long-form essay into a listicle — “8 reasons why this React component is complicated”.

It make it easy to scan through a component and find just the pieces of functionality you want. I found pleasantly few surprises working on components written with recompose (barring misuse, of course). For example, in the class version, I would’ve not noticed that Foo was using context since the code was buried deep within a method’s body.

So… Recompose all the things?

Well, that’s what I tend to do anyway. There are situations where you’ll probably want to use classes (e.g. for refs), but otherwise, recompose components tend to be easier to scan –– your code reviewers will thank you! Even though it feels foreign at first, recompose is surprisingly easy to pick up. The next time you encounter a hairy class component, think about how recompose might help.

Abdul Nimeri

Written by

Software Engineer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade