GraphQL Code Generator - Introducing Hooks support for React Apollo plugin

Leonardo Ascione
GraphQL Code Generator - Introducing Hooks support for React Apollo plugin - The Guild Blog

If you follow the React community, you’ll know for sure that React Hooks 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 or with auxiliary libraries.

In case you don’t know what hooks are, you may be wondering what all this buzz is about. Let the React docs 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

tip

If you already know all about hooks and @apollo/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!

There are many hooks, like useEffect or useReducer, that may simplify your code, but I’ll leave this to your curiosity. I suggest you to read the Dan Abramov (“Making sense of React Hooks” 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._If

The new hook useContext allows us to access a React Context (with its Consumer/Provider api) directly from a functional component, without props nor contextType:

// 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 or render-props callback hell 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:

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

  return (
    // ...
  );
}

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:

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 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, 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:

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

And here we can see autocomplete at work:

If you want to see graphql-code-generator in action, you can look at the awesome WhatsApp-Clone-Client-React project made by The Guild. Here is the diff (thanks to Eytan Manor) 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!