React tips — Recompose

Leonardo Bruno Lima
5 min readMay 4, 2018

--

Photo by Hunter Haley on Unsplash

Recompose is a library for React/Redux created by Andrew Clark. It is a utility belt for React and it’s really very good and helpful.

In this post I’ll create a example of a card of dog’s breed list and I’ll been using only functional components and recompose.

First, let’s get stated with the create-react-app:

$ create-react-app react-recompose-dog-breed

Let’s make some changes on file structure to looks like this:

I’ll let the root index.js file very simple and with a hardcoded list:

On header.jsx we just leave a title:

On dog_card.jsx let’s do this:

And finally on app.jsx let’s change to looks like this:

If you run the app, you could see something like this:

Alright, now let’s start to use the Recompose component. First add it to the project:

$ npm i recompose

Now, let’s change our code to allow user click on card and make it close and open. You can to this using a local state, but in order to do this, you need to change this component from functional component to class based component and we don’t want to do this. So, let’s use recompose!

The first component we will use is withState. It’s a high order component and works like connect from Redux. withState acepts 3 argments: state name which is the name that will be added to the props as state value, state updater name is the name of function you can call to update the state and initial state. A bit confusing, so let’s do an example:

Let’s change the dog_card.jsx file to this:

In this case, I’ve imported the withState and defined the first argument as opened so I can use it to check if the card is open or not. The second argument is the name of the function I will use to set the card opened or closed (withState will create it automagically for us, this is the magic of HoC) and the third argument is the default value.

If you run the app you can see this:

Ok, almost there. Now let’s keep using recompose to allow us to open the cards. In order to do this, let’s use setCardOpen function.

I just call this function on the onClick event passing the opposite value of opened.

Remeber: both the opened and setCardOpen were create by withState high order component. I know it seems magic.

Now, if you run the app you can toggle the cards like this:

But there’s a problem here. We are using anonymous function to handle click and this function will be created every time the component re-render. So, let’s create it outside the render phase using another HoC: withHandlers.

In order to use withHandlers we need to (or should) use another HoC called compose. Let’s to this.

Import these two HoC:

import { withState, withHandlers, compose } from 'recompose';

Now, let’s change the dog_card.jsx file to look like this:

Using compose, we can mix as many HoC we can and in this case we’ve created a new one called enhanced. It is composed by withState and withHandle. The withHandle accepts custom event handles and we created just one handleClick.

The last component I will show is the Branch. We are going to use it to show a spinner while the date didn’t load. Of course you can do it inside your component with conditionals, but I want to show you another way to do that. So, change the root index.js to add a timeout to simulate fetching data:

// Init with empty array
ReactDOM.render( < App breeds = {[]} />, document.getElementById('root'));
// After 2 seconds load the data
setTimeout(function() {
ReactDOM.render( < App breeds = { dogs_breed } />, document.getElementById('root'));
}, 2000);

Create two files: Spinner.jsx and Spinner.css

Now, go to the app.jsx and do some import:

import { branch, renderComponent } from 'recompose';

It should be like this:

If you run the app you can see the spinner while array is empty:

Well, as you can see the recompose component can help us in many tasks. For more details you can check the documentation and feel free to ask me anything. You can clone this repo here: https://github.com/lblima/react-recompose-01

Thanks for reading!

--

--