Giving stateless, functional components “state” with recompose

I wrote about the recompose lifecycle higher-order component in my previous story, but lifecycle is only a small part of what recompose has to offer.

I recently needed to create an email capture component that existed independently of my application’s state management. There is, of course, the straightforward, class based way of making a stateful component.

This pattern is pretty simple. It works really well, but I like my components to be functions. This is where recompose comes in. Let’s use the withState and withHandlers higher-order components with compose to clean that up.

Wow! I saved several lines of code and ~60 keystrokes, but the real gains here are less obvious. The higher-order components are descriptively named, so you have a rough idea of what they provide at first glance. The initial state is also very clear once you understand the function signature of withState. The withHandlers higher-order component makes defining callbacks for your stateless component very straightforward and saves you from the scope issues of a class based component. It will also reserve the identity of handlers across renders rather than creating a new function each render like in the case where handlers are defined in the function body. Finally, what I find most valuable, is the ability to pass spies as props when it’s test time.

Now with just a few assertions and two snapshot tests we have pretty good test coverage on the meat of our component. The recompose bits are consistent, and as long as we use them correctly there’s not much to worry about there.

Conclusion

The recompose library is a powerful toolkit. We’ve seen here how withState and withHandlers can quickly and easily make a stateless, functional component have some “state” associated with it while still being pure and easily testable. Check out my previous story about the lifecycle higher-order component.

Thanks for reading!