Mutations in Apollo w/ Recompose

Since Sashko Stubailo launched his post about Apollo + Recompose, which is a great blog post by the way, I wanted to show everyone how I use Apollo and Recompose to do my Mutations at the UI level.

Today we’re just going to go through a quick UI Component.

Pretty simple, it’s a button! This is how I usually build my UI’s. I start with a stateless component and keep the interface to the component STRICTLY with props. Once the component is ready and pretty, time to integrate the functionality we need.

1. Setup Compose

Whenever I get into HOC development I immediately import the compose function and setup my code like this:

More often than not, I know I’m going to be composing multiple HOC Functions together.

2. Context HOCs

Since compose is just flowRight from lodash, I want to make sure I’m building up my component in the correct order. I usually start with my components that give props inherited from a context or some Provider component.

For our example, I’d like to provide my component the intl prop from react-intl. This comes from the IntlProvider somewhere in my component hierarchy above this component.

Last in the realm of context HOCs, I’d like to bind my GraphQL mutation to this component as well. For that we’ll use the graphql container from react-apollo. This comes from the ApolloProvider somewhere in my component hierarchy above this component.

Now as we add more HOCs in this chain, they will have access to the props provided by our context HOCs. Specifically we’re interested in the intl and mutate properties.

3. Event Handling

Okay we all know this by now I hope, DO NOT .bind or use Arrow functions in JSX props. I had a coworker who would fight me on this everyday. Glad to say they are not with us anymore. A bind call or arrow function in a JSX prop will create a brand new function on every single render. Good thing recompose thought of that:

withHandlers takes a map of Higher Order Functions that accept props and return function handlers. Handlers are passed as immutable props and are preserved across renders. Thus, we avoid the pitfall of React components creating new handlers on every render. Furthermore, if you are trying to do any type of prop equality, these new renders will screw up your assumptions.

For Mutations, the graphql container does have options for you to create props, BUT having adopted the recompose workflow prior to using Apollo, I got to stick with using withHandlers for creating my Mutation handlers.

4. Don’t forget your Component!

I can’t tell you how many times I’ve tried to debug this stupid mistake. If you have been following along you know that at this moment we haven’t actually composed our original MutationButton! I always forget this and I hope you make sure you don’t!!

All together now:

Conclusion

When we talk about “containers” or “component composition” we are talking about Higher Order Functions. They take a function and return a Function. Recompose has absolutely changed how I develop React components. Function components have so many advantages.

  • You won’t be relying on this setState / this.state mess that some components have.
  • They encourage separation of concerns
  • Your code is now very modular
  • They tell Giant, Complicated, Big, React classes to take a hike