(This article is also available on graphqlmastery.com without the paywall.)
EDIT: This article will be updated soon as Apollo has release official React Hooks implementation. However, the core concepts described here are still valid.
The hype following the last React conference has diminished. The proposal for React Hooks was introduced as part of the React alpha release. Since React v16.8, React Hooks have been in all official release as well. How does this improvement affect how we build our apps with GraphQL?
We usually take our time before introducing new tech features in our projects at Atheros. This will allow us to not jump on the false hypes. React Hooks are now tested and production-ready, so we took a shot on implementing it in our projects as well. React Hooks is a new way how to reduce the need for React component classes and their lifecycle methods. They also solve other problems related to using HOC (Higher order component) or render props pattern. There are a lot of resources on React Hooks and I will not go deep into them from React standpoint in this article. You can check out the following talk from the recent conference
The official React library comes with its own default Hooks such as useState, useContext, useEffect and others . The React library does not, however, contain Hooks for executing GraphQL queries and mutations in the Apollo client. Let’s take a look at these now. First, let’s summarize how we currently fetch data with Apollo and React.
Apollo client API
With the Apollo client and React, you can query your GraphQL server in various ways. We currently have three major ways to query our GraphQL server.
- HOC pattern
- Render props pattern
- React Hooks
We will show how these approaches work using the simple component for displaying a list of emails. The GraphQL query looks like this:
It will be useful to check out the repository with examples. You can clone the repository with…
git clone email@example.com:atherosai/next-react-graphql-apollo-hooks.git
and then, to preserve package-lock.json dependencies, install with…
You can run dev server as follows…
npm run dev
HOC (Higher-Order Component) pattern
As far as I know, this is the oldest execution method for queries and mutations with Apollo. It uses the well-known React HOC pattern. This pattern is implemented in React Apollo using the HOC component created with the graphql function. We can use this function to define further HOCs for a different GraphQL query or mutation. With this approach, we can write our simple component as follows:
The disadvantage can be that if we have many mutations or queries, it can become impractical to maintain so many HOCs. In some cases, you even need to keep the HOCs in order if you use, for example, the withApollo component as well. In these cases, to clean up the code we can use compose utility from the React Apollo package, or just use the recompose library.
Render props pattern
Currently, render props is the official way to handle GraphQL queries and mutations in Apollo. There is no need to wrap the components with HOCs. The HOCs created with graphql() have been replaced by the Query and Mutation components. The rewrite for our simple component above is easy.
You are still able to use both ways of executing queries in Apollo, but the render props pattern is the primary way in the official documentation. You can also check out this article on pros and cons of higher-order components, render props, and React Hooks .
Using React Hooks with GraphQL in Apollo client
React Hooks do not have official support in the React Apollo library (edit: the official package is now released, the article will be updated soon), but you can watch opened issue on React Hooks in Apollo client. The community has already prepared unofficial implementation. For us, it is completely sufficient, and we really love the simplicity of using it. The library is called React Apollo Hooks. Even though you can reinvent the wheel and try to prepare the Hooks by yourself, I would suggest using already-prepared Hooks. The library also supports SSR and has experimental support for Suspense. The first thing that you need to do is to wrap your top-level component with the Hook provider. We use Next.js in our example project, so a good place to do this is in __app.js file.
The Apollo Hook Provider enables us to use React Hooks for executing queries and mutations in our application. The following Hooks are available in the React Apollo Hooks package: useQuery, useMutation and useSubscription.
GraphQL queries with React Apollo Hooks
Let’s take a look at the component for fetching emails that we wrote with the HOC and render props pattern. We will import the useQuery Hook from the React Apollo Hooks library. Now let’s define our first Hook for a GraphQL query. Hooks need to be defined in the body of functional React components. The new implementation with React Hooks is as follows:
We can see that the API is simple to use, and also the useQuery Hook returns the same variables as usual. Now let’s take a look at how we can define variables and manually update the cache.
Writing our GraphQL mutations with React Hooks
We can define the useMutation Hook in a similar way. In a similar way, we define useMutation Hook as well. As we know, the main difference between a query and a mutation lies in their different execution. Queries are executed in parallel, but mutations are executed serially. Let’s take a look at how to execute the subscribeEmail mutation using the useMutation Hook.
We have written our component with the excellent Formik and Yup validation library. We can see that the Hooks definition is done without variables. In the React Apollo Hooks library, we can either define variables in the body of a functional component or pass them dynamically once the Hook is executed. The API for updating the cache is also the same as in React Apollo.
I hope that you like this short article on using React Hooks with GraphQL. You should be aware that the final official implementation in React Apollo might be different from the community library. But I would give it a try if you are looking forward to using Hooks in your GraphQL projects. We really enjoy using it. To ease your Hooks setup with Apollo, you can use our example repository to speed up the process.