GraphQL Code Generator - Hooks support for React Apollo plugin
Tags: graphql, codegen, react, reactapollo
Published: 2021-07-29 08:58:51

> This article was published on Friday, March 1, 2019 by [Leonardo Ascione](https://twitter.com/leonardfactory) @ [The Guild Blog](https://the-guild.dev/)

If you follow the React community, you'll know for sure that
[React Hooks](https://reactjs.org/docs/hooks-intro.html) had been one of the most awaited feature in
the ecosystem since their first gist. They have been available since React v16.7-alpha, and many
libraries already started adopting them —
[officially](https://react.i18next.com/latest/usetranslation-hook) or with
[auxiliary libraries](https://github.com/facebookincubator/redux-react-hook).

<Video src="https://youtube.com/embed/dpw9EHDh2bM" title="React Today and Tomorrow and 90% Cleaner React With Hooks" />

In case you don't know what hooks are, you may be wondering **what all this buzz is about**. Let the
[React docs](https://reactjs.org/docs/hooks-intro.html) speak for itself:

> Hooks let you use state and other React features without writing a class.

This could be a huge improvement by itself (you know, you create a Functional Component, mess with
it, and then you need a bit of state so... let's refactor this to a class, hooray! 🎉 — sarcasm is
intentional), but there is more.

## React Apollo and Hooks

<Callout>
  If you already know all about hooks and [@apollo/react-hooks](https://apollographql.com/docs/react/api/react-hooks), and want to see the news about `graphql-code-generator`, just skip this section.

  If you are interested in the long story instead, keep reading!
</Callout>

There are many hooks, like `useEffect` or `useReducer`, that may simplify your code, but I'll leave
this [to your curiosity](https://reactjs.org/docs/hooks-overview.html). I suggest you to read the
[Dan Abramov](https://twitter.com/dan_abramov)
([“Making sense of React Hooks”](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889)
story if you didn't already.

What I want to talk about, instead, is `useContext` and how you will fall in love with it,
especially when talking about `react-apollo`.

**Note:** If you haven't used Context before, just think of it as a way to pass props down the
components' tree without passing props down component-by-component. It should not replace normal
React usage, but is useful when talking about cross-application values like state, translations,
themes, etc.

The new hook `useContext` allows us to access a React Context
([with its Consumer/Provider api](https://reactjs.org/docs/context.html)) directly from a functional
component, without props nor contextType:

```tsx
// This is our custom hook
function useThemeColor() {
  const theme = useContext(ThemeContext)
  return theme.color
}

function MyComponent(props: Props) {
  // Here we go
  const color = useThemeColor()

  return <h1 style={{ color }}>{props.title}</h1>
}
```

Given this sweet feature, we can now think about all our HOCs / Render Props in our codebase, well,
almost all: Every time we need to access context (*State Management, API Calls, Translations,
Localization*) we can now use hooks.

Especially using TypeScript, deep
[HOCs tree-hell](https://reddit.com/r/reactjs/comments/85h93f/higher_order_component_hell) or
[render-props callback hell](https://medium.com/@ntgard/why-i-dont-use-render-props-in-react-10f18abdff11)
are a nightmare (Reminding Node.js callback hell, anyone?). Typings are always wrong, you need to
define twenty different interfaces, etc.

With hooks, you can just use them in a straight, linear, fashion:

```tsx
function MyComponent(props: Props) {
  const translate = useTranslation();
  const { user } = useMappedState(state => state.user);

  return (
    // ...
  );
}
```

[**React Apollo**](https://github.com/apollographql/react-apollo) fits perfectly the requirements,
and it now supports Hooks for your GraphQL operations.

If you are used to `Query` component, in the next example you'll see how we are replacing it with
just the `useQuery` hook:

```tsx
import { useQuery } from '@apollo/react-hooks'

const GET_TODOS = gql`
  {
    todos {
      id
      description
    }
  }
`

function Todos() {
  // Here the magic bits
  const { data, error, loading } = useQuery(GET_TODOS)
  if (loading)
    if (error)
      // ...
      // ...

      return (
        <ul>
          {data.todos.map(todo => (
            <li key={todo.id}>{todo.description}</li>
          ))}
        </ul>
      )
}
```

## React Apollo Hooks and GraphQL Code Generator

Since the first time I saw hooks, I thought about removing the callback hell caused by render props
in my codebase. Given the awesome work done by Daniel Trojanowski with `react-apollo-hooks`, I
wanted to use **hooks** in our projects, replacing React Apollo classic components (*render-props
based*).

However, I love even more the [`graphql-code-generator`](https://graphql-code-generator.com)
project, since I want proper **typings** with my Query, Mutation and Subscription components.
Accessing `data` with proper autocomplete and type checking is definitely a game-changer!

> I'm glad to have the honor to announce the next release of GraphQL Code Generator, that will add
> React Apollo hooks generation to its arsenal

With this enhancement, now you can choose between React Apollo Components, HOCs or Hooks and even
mix-and-match if you've got an existing project and want to start using Hooks right now!

Just use GraphQL Code Generator's
[Typescript-React-Apollo Plugin](https://graphql-code-generator.com/docs/plugins/typescript-react-apollo),
set `withHooks: true` to your GraphQL Code Generator config, and add `react-apollo-hooks` to your
dependencies if you already didn't.

This is an example generated hook, with proper typings:

```tsx
export function useUserListQuery(baseOptions?: QueryHookOptions<UserListQueryVariables>) {
  return useApolloQuery<UserListQueryQuery, UserListQueryVariables>(
    UserListQueryDocument,
    baseOptions
  )
}
```

And here we can see autocomplete at work:

![](https://the-guild.dev/blog-assets/graphql-codegen-hooks-support-react-apollo/vscode.png)

If you want to see `graphql-code-generator` in action, you can look at the awesome
[WhatsApp-Clone-Client-React](https://github.com/Urigo/WhatsApp-Clone-Client-React) project made by
[The Guild](/). Here is the diff (thanks to [Eytan Manor](https://medium.com/u/5a6962cd709e))
showcasing the generated hooks applied to a real codebase.

## Conclusions

React Hooks will probably be a powerful tool in our toolbelt, and I'm sure we will see many patterns
evolving. Libraries like React Apollo fits perfectly, and I hope having tools to generate typings
like GraphQL Code Generator will increase their adoption.

I'd like to thank the awesome team behind The Guild, especially Eytan Manor for its continuous
effort reviewing my hooks proposal, Arda TANRIKULU and Dotan Simha for their support and, obviously,
the creation of `graphql-code-generator`. Thanks indeed to Daniel Trojanowski for the great work on
the initial implementation of hooks in `react-apollo-hooks`.

Thank you for reading this story, I hope you found it useful/interesting. May the hook be with you!