Using GraphQL with Hooks
Tags: react, graphql
Published: 2019-03-08 12:27:53

---
title: Using GraphQL with Hooks
published: true
description: In this blog post we will see how we can use GraphQL with new React Hooks api
tags: React, GraphQL
---
![](https://thepracticaldev.s3.amazonaws.com/i/tdq5mn9e1ce11xyo05tq.png)

React Hooks is a new React api, that came in 16.8 version and since then has been getting a lot of buzz. The reason for that is mostly that now we don't really need to create class components for using state or lifecycle methods. In fact you can ditch lifecycle methods completely, cause with hooks you can use `useEffect` for anything you've used previously for lifecycle methods.

So now when hooks are out let's see if we can use GraphQL with hooks. But before let's discuss in a nutshell how we can use GraphQL with React and Apollo.
This post will assume you have basic knowledge of GraphQL, but if you don't, you can check my free [online bootcamp](https://www.youtube.com/watch?v=Jl7oYk7Ye9E&list=PL28aKhmSneX86qqmzVNjwYJ1OZORPFxAr) with 9.5h of live coding and teaching lost of aspects of GraphQL.
In the following code snippet we are setting our `ApolloProvider` for queries, mutations and subscriptions. Also our GraphQL API endpoint has an access key so we create an authLink and wrap our `httpLink` with it. for `WebSocketLink` we set our headers inside `connectionParams`.

{% gist https://gist.github.com/vnovick/53b61b02a845eb0d53863d2194a95775 %}

Our GraphQL API is auto generated with [hasura.io](http://hasura.io) free and open source engine, so if you are interested in learning more about that you can check the following video:

{% youtube 5zvb2jKlsKw %}


In the snippet above we set up our `ApolloProvider` and pass it with our `ApolloClient` configuration. Now it's time to query our GraphQL endpoint.

We do that with `Query` component imported from `react-apollo` and providing it with render prop, which will get either query result `data`/`error` or `loading` states. It looks like this:

```react
import { Query } from 'react-apollo'

export const Posts = () => (
  <Query query={getPosts}>
    {({ data, loading, error }) => {
      console.log(error);
      if (error) return null;
      if (loading)
        return <div>Loading...</div>;
      return data.posts.map(post => (
        <div>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
        </div>
      ));
    }}
  </Query>
)
```

Mutation will look similar but instead of having `data`,`error` and `loading` states it will provide mutation function as first argument. whichever data we send as an argument to this function will be passed to our GraphQL mutation 


```react

<Mutation mutation={addPost}>
      {(addPost, { data }) => (
        <div>
          <form
            onSubmit={e => {
              e.preventDefault();
              addPost({
                variables: {
                  title: title.value,
                  content: content.value,
                  authorId:
                    '2808238d-5365-4a70-af52-1de6178bb090'
                },
                refetchQueries: [
                  { query: getPosts }
                ]
              });
            }}
          >
          </form>
      </div>
    )}
</Mutation>
           

```


Subscriptions will look pretty much the same as queries, so I won't include basic example.

## It's time to change everything to work with Hooks!

Let's get back to our App.js. Nothing will change there, but instead of using 

```react
import { ApolloProvider } from 'react-apollo'
```

we will use 

```react
import { ApolloProvider } from 'react-apollo-hooks'
```

Now inside our `Posts` component we won't use Query anymore.
we will import `useQuery` from `react-apollo-hooks` and use it in the following way:

```react
import {useQuery } from 'react-apollo-hooks';

export const Posts = () => {
  const {loading, data, error} = useQuery(getPosts);
  if (loading)
    return <div>Loading...</div>
  if (error) return <div>Error</div>;
  return data.posts.map(post => (
    <div>
      <h3>{post.subject}</h3>
      <p>{post.content}</p>
    </div>
  ));
};
```

Now for mutation instead of using RenderProp we can also use `useMutation` from `react-apollo-hooks` and use it in the following manner:

```react
  const addPostMutation = useMutation(addPost)
  
  return (
        <div>
          <form
            onSubmit={e => {
              e.preventDefault();
              addPostMutation({
                variables: {
                  subject: title.value,
                  content: content.value,
                  userId:
                    'a29aa6ae-8cfc-43f9-997e-73baf21835d8'
                },
                refetchQueries: [
                  { query: getPosts }
                ]
              });
            }}
          >
         </form>
       </div>
  )
```

Using mutations and queries as hooks help us a lot with nesting of our Mutations and Queries. Consider this:

{% gist https://gist.github.com/vnovick/39c50b945268a66cf5ed90745e0f0ca4 %}

In this gist you see nesting of query inside a mutation. 
Now take a look at implementation with hooks:

{% gist https://gist.github.com/vnovick/0c2425c6dc73055c1dbee45474517e9e %}

Not only it looks cleaner, we've also added setState hook to change our inputs to be connected to PostMutation state.

Now let's take a look at subscriptions.
The only thing that we need to change in our Posts component is to change getPosts query itself to be subscription 

```react
const getPosts = gql`
  subscription getPosts{
    posts {
      subject
      content
    }
  }
`;
```

and import  `useSubscription` from `react-apollo-hooks` instead of using `useQuery`


```react
export const Posts = () => {
  const {loading, data, error} = useSubscription(getPosts, { suspend: false });
  if (loading)
    return <div>Loading...</div>
  if (error) return <div>Error</div>;
  return data.posts.map(post => (
    <div>
      <h3>{post.subject}</h3>
      <p>{post.content}</p>
    </div>
  ));
};

```

[react-apollo-hooks](https://github.com/trojanowski/react-apollo-hooks) has lots of additional stuff inside like **experimental** `Suspense` support for example. In a nutshell it means that instead of getting `loading` state from useQuery, we now can wrap the component with `Suspense` and provide it with a fallback for our loader.
Like this:

```react
export const App = (
    <ApolloProvider client={client}>
         <Suspense fallback={<div>Loading...</div>}>
          <Posts/>
        </Suspense>
    </ApolloProvider>
)
```

## Conclusion 

So to summarize. Using GraphQL with Hooks is really straightforward and hopefully at some point we can benefit from using GraphQL with hooks at official Apollo client. Currently you can use it with [react-apollo-hooks](https://github.com/trojanowski/react-apollo-hooks) library.

Also if you are interested in learning more about GraphQL, Serverless or Web, Mobile, AR, VR or IoT in general, follow me on [Youtube](https://www.youtube.com/channel/UCxiXx-gMssQnY0hTt5bStpw) or on [Twitter](https://twitter.com/vladimirnovick)