Feather
6 min readAug 12, 2018

--

The TLDR; part of this story is use recompose if you are a React developer. Now I’ll explain why.

A bit of history. In late 2016 I moved from Ember to React to write a smallish internal app at Netflix. This was a pretty basic React app. While it was visually complex, the app wasn’t really altering a lot of data.

Lots ofsetState() and dumb presentational components ensued. The app worked beautifully. Coming from two very large, opinionated frameworks (Angular and Ember) we were two converts to React who were really embracing the beauty in simplicity. You can select only what you need from the buffet of architectural options.

In our first iteration we added redux, because we just figured you need it. Then we realized redux was adding needless complexity. We tore out our actions, reducers, etc, and went back to setState(). It was so easy to write tests, since we didn’t have to wrap every component in a huge taco of mock dependencies to test it.

After leaving Netflix my primary goal was to sink my teeth into a large, complex, customer-facing React app. I wanted to get down and dirty with lots of complex state management and finally answer the question of how that simplicity I had so admired might scale.

Fast forward to 2018 and I find myself Knee-deep* in a complex React app with react-redux, and HOCs galore. This app is creating a platform for AI on NVIDIA GPU cloud servers. It is essentially trying to make data science more friendly for a wider audience.

The app is complex and it is right on the wild frontier of things that have not yet been done with React. Yeehaw! To handle the complexity there is wide use of functional paradigms. Higher Order Components abound. When I first landed in that codebase I had a Dorothy moment, because I was definitely not in Kansas. It didn’t look like the React I’d become so confident and comfortable with. Every component is a stateless functional one, and state gets passed in through props.

This is the beauty of recompose. When I saw(first thing)(second thing) and it was not redux connect(), it provoked a thorough round of head scratching. Then I realized this is how there are no class components. Recompose is decorating stateless functional components with state and event handlers. It makes the code far more readable, once you understand the pattern.

Recompose touts itself as “a React utility belt for function components and higher-order components”. Personally, I like to think of it as functional training wheels. You might not think you need this, and indeed you may not. It does answer the question of how to scale while maintaining that beautiful simplicity that sold me on React to begin with.

First, though, some background on the Decorator pattern, as this will provide useful context. The concept goes back to at least the 90’s with the Gang of Four book on Design Patterns. They described it as a structural pattern that “dynamically adds/overrides behaviour in an existing method of an object.” Basically, it takes a generic object and adds a layer of functionality without corrupting the underlying simplicity. Below is a helpful visual.

Decorate it for a more beautiful Dwight object.

A really useful example is adding validation to a form. Your form can be a simple, stateless presentational component that gets decorated by a validation class. While your form still gives useful feedback to someone trying to fill it out, it’s just a dumb presentational component. This enhanced logic comes from a separate class. You might have seen this done with inheritance if you had an object-oriented past life. But this is far more lightweight and flexible than classical inheritance.

Most of us who have been at it for a while know that we should really avoid stateful components in React. But if you’ve ever had a codebase with lots of stateless functional components you have probably felt the pain of needing to add state back into them. What if I told you that you can write all of your components as stateless functional components and leave them that way. Forever!

Then I would, of course, follow this statement with several peals of evil laughter, just for good measure.

When you need stateful behavior, you can simply decorate stateless functional components with state using recompose(decorator)(component). The pattern is very simple. It opened my eyes to what can be done with functional decorator patterns.

Below is a simple counter using recompose. For the whole repo click here.

What it looks like
The code

By now you have undoubtedly written a counter or two. Usually there would be a class function that looked a bit more like the code snippet below. You can also visit this code on GitHub if you are yearning for more.

All of that is now handled by the incrementCount function. Where is this function defined, you ask? This is what I love. You never need to write a simple boilerplate setter function again. You just tell recompose that you are creating a handler function that does an operation.

Using withState you tell it the name of the state variable, the name of the function, and the initial value of the state variable (in that order). Then you use withHandlers to name your function and tell recompose what it does. Boom. You pass in whatever you are setting your variable to. Then you attach your handler to the DOM elements that needs it with onClick or onChange. More booming.

You may have heard that it’s best to use functional setState so that you can use your previous state to determine current state and thus avoid race conditions associated with asynchronous operations. If you hadn’t heard that before, well now you have. As a bonus you kind of get this for free with recompose.

All of the state variables get passed into your component as props. You can then just use them as needed to determine how your component should render. The withHandlers decorator updates state variables based on the current value found in the props object. Basically you can think of props as state now.

There is a tie-in to lifecycle methods, too, if you need them. You can even use setState in those, if you so desire. Here is a classic data-fetching example. This isn’t production-ready code, but more an illustration.

This repo is for a typeahead search. It’s still being refined, but basically works, when the API isn’t too grumpy. I’m using componentDidUpdate because I need my component to update when the search input gets new data. Since the GitHub API is not keen on getting hit a zillion times with unauthorized requests, I limited new searches to anything over 3 characters. It still locks me out after a few searches, so meh.

And holy crap, look at that style! I’m practically a designer.

Empty search
With search results

There are tons of other really neat things you can do with recompose. I’ve only scratched the surface here. One of them is branch. Maybe I’ll save that for another day, though.

Recompose is also designed with Observables in mind, so there are handy helpers for that. A very succinct article on that can be found here. He’s building a typeahead search with recompose and RxJs using componentFromStream, which is probably what I’ll end up doing in the production version of my typeahead search. Personally I find it useful to build things in small bits that I understand then rewrite them in a more concise manner afterwards.

For further reading, I highly recommend the recompose docs. Happy coding!

*I’m always Knee deep, because it’s my name!!

--

--

Feather

Thoughts on code, climbing, and DIY. JavaScript, Elixir, and other fun stuff.