How to master Redux and Apollo’s HOCs in Typescript.

Jannes Vandepitte
Aptus
Published in
5 min readFeb 8, 2018

--

We’ve spent a lot of time figuring out how we could best create reusable components and the best way to get everything typed correctly. After a lot of debating back and forth between colleagues we finally found a great way to implement it all. And we thought you might like it as well.

So, what are HOCs ?

First of all let's quickly go over what HOCs are exactly. And why they can be so useful. According to the official React docs a higher order component is described as such:

A higher-order component is a function that takes a component and returns a new component.

That’s all fine and dandy but why would I use one? Well, let’s say you you have a few components that take in a loading prop and based on that prop you’d either show the content or the loading indicator. Without a HOC you’d be retyping that code in each component. See DRY.

With a HOC however you could wrap each component inside it and return the component when loading is false and an indicator when loading is true.

You’ve probably already used a HOC before if you’ve ever used redux’s connect.

How to use them ?

If you’re only using one HOC, easiest way to use them would be as follows:

As you can see the code is pretty straight-forward. And this method is perfect if you’re only using one HOC. If you’d want to use multiple it would become rather confusing and tiresome.

Composing

That’s where compose comes into play. If you’ve never heard of function composition, it’s basically combining(or composing) multiple functions to create more complex ones. This does not only apply to react components but to basically any function. You could write a compose function yourself and it would look something like this:

Note: This is a very basic example of a compose function. It executes the functions in reverse order.

In this example it first parses the string to a floating point number and then rounds it.

Now that we know what composing is, it’s pretty straightforward to use it. Luckily Redux already includes a compose function so we’ll use that.

Let’s say we want to fetch a user with a GraphQL query based on the userID in the redux store. We could accomplish this like this:

Redux’ compose works from left-to-right so we inject Redux first because we need the injected userId in the query. Next we add the query responsible for fetching the user based on the given userId .

As you can see it’s very simple to chain multiple HOCs together, but do remember, the order in which you add them matters.

Note: The typings above are not persé correct as I pass ProfilePageProps to the graphql HOC and not all of those props are set already. This could be fixed by creating an extra interface combining all the HOCs I used before the withUsersQuery with the ProfilePageContainerProps but that’d be rather tiresome when you’re using multiple HOCs.

But wait, there’s more.

You might’ve noticed that the variables and queries are typed in the last example. You could write these yourself if you’re feeling brave and have a lot of spare time. Or you can generate types based on a GraphQL schema it fetches from the server or an introspection JSON you provide.

We chose to do the latter. We first used Apollo Codegen but later discovered GraphQL Code Generator. The first one gets the job done, but the types GraphQL Code Generator generate are just way ahead of Apollo Codegen’s types. Mainly the way it namespaces the queries/mutations and create the types for “subfields” as well.

Using it is pretty straightforward, simply install gql-gen globally:

npm i gql-gen -g

And simply generate the types like this:

gql-gen — url localhost:3001/grapgql — template ts-multiple — out ./src/models/graphql/ \”./src/graphql/**/*.graphql\””

This fetches the schema from localhost:3001/graphgql and outputs the results based on queries/mutations found in ./src/graphql/** to ./src/models/graphql/.

Custom props

If you’re like us and don’t really like how Apollo crams all its info in the data props you could specify how the HOC should pass them to the component.

For a query you could do something like this:

In this example the HOC create 3 props on your component:

  • users : An empty array or an array with users.
  • usersLoading : A boolean representing the loading of users.
  • usersError : An optional error returned by Apollo.

This is especially handy if you’re using multiple queries on one component.

Why we don’t use the name option provided by Apollo to rename the data prop to something else ? Well first of all because it’s not really possible to get that typed correctly. And doing it our way further decouples the presentational component from any logic. It just expects users and usersLoading and doesn’t quite care where it comes from.

For a mutation we could do something like this:

In this example the HOC just passes one prop to the component, login() . Which you can use like this:

As mentioned before this is a beautiful way to decouple your components. You could quite easily change the backend from Apollo to anything else and your presentational component wouldn’t be the wiser.

Conclusion

I’ve learned a lot in the process of figuring out how to best decouple container components from presentational components and I’m really glad to share my/our findings with you.

Happy typed coding!

I’m Jannes, working as a Javascript developer at Aptus. Our mission is to craft digital endpoints for the physical world. We support companies in their new digital ventures by inventing, creating and developing tools, applications and Internet of Things solutions. We are creative technologists who approach innovation differently: we experiment, tinker and make ideas come to life from the earliest moment possible.

--

--