This article was published on Friday, March 1, 2019 by Leonardo Ascione @ 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
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.
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!
Top comments (0)