Need help with react-apollo-hooks?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

trojanowski
2.4K Stars 116 Forks MIT License 94 Commits 85 Opened issues

Description

Use Apollo Client as React hooks

Services available

!
?

Need anything else?

Contributors list

# 91,747
GraphQL
ssr
React
apollo
67 commits
# 19,193
React N...
render-...
formik
vercel
9 commits
# 13,812
TypeScr...
mobx
yarn
reactjs
2 commits
# 310,514
Kotlin
dao
SQL
ant-des...
1 commit
# 139,761
HTML
React
inferno
GraphQL
1 commit
# 75,654
React
paralle...
Redux
Shell
1 commit
# 82,624
Less
Shell
nextjs
Markdow...
1 commit
# 83,551
repl
hierarc...
Django
GraphQL
1 commit
# 417,807
TypeScr...
JavaScr...
1 commit
# 70,629
TypeScr...
HTML
Angular
Express
1 commit
# 240,364
TypeScr...
C#
cordova...
cordova...
1 commit
# 41,368
Ruby
Elixir
capistr...
TypeScr...
1 commit
# 407,663
TypeScr...
CSS
1 commit
# 52,792
Algolia
React N...
algolia...
travisc...
1 commit
# 356,340
HTML
CSS
Vim
vim-plu...
1 commit
# 419,462
TypeScr...
JavaScr...
1 commit
# 376,678
TypeScr...
Shell
PHP
1 commit

react-apollo-hooks

This library is deprecated. Please migrate to the official React Apollo Hooks.


Use Apollo Client as React hooks.

CircleCI

Installation

npm install react-apollo-hooks

Or if using yarn

yarn add react-apollo-hooks

Example

https://codesandbox.io/s/8819w85jn9 is a port of Pupstagram sample app to react-apollo-hooks.

API

ApolloProvider

Similar to ApolloProvider from react-apollo. Both packages can be used together, if you want to try out using hooks and retain

Query
,
Mutation
,
Subscription
, etc. HOCs from
react-apollo
without having to rewrite existing components throughout your app.

In order for this package to work, you need to wrap your component tree with

ApolloProvider
at an appropriate level, encapsulating all components which will use hooks.

Standalone usage

If you would like to use this package standalone, this can be done with:

import React from 'react';
import { render } from 'react-dom';

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

const client = ... // create Apollo client

const App = () => ( );

render(, document.getElementById('root'));

Usage with react-apollo

To use with

react-apollo
's
ApolloProvider
already present in your project:
import React from 'react';
import { render } from 'react-dom';

import { ApolloProvider } from 'react-apollo'; import { ApolloProvider as ApolloHooksProvider } from 'react-apollo-hooks';

const client = ... // create Apollo client

const App = () => ( );

render(, document.getElementById('root'));

useQuery

import gql from 'graphql-tag';
import { useQuery } from 'react-apollo-hooks';

const GET_DOGS = gql { dogs { id breed } };

const Dogs = () => { const { data, error, loading } = useQuery(GET_DOGS); if (loading) { return

Loading...
; }; if (error) { return
Error! {error.message}
; };

return (

    {data.dogs.map(dog => (
  • {dog.breed}
  • ))}
); };

Usage with Suspense (experimental)

You can use

useQuery
with React Suspense with the
{ suspend: true }
option. Please note that it's not yet recommended to use it in production. Please look at the issue #69 for details.

Example usage:

import gql from 'graphql-tag';
import React, { Suspense } from 'react';
import { useQuery } from 'react-apollo-hooks';

const GET_DOGS = gql { dogs { id breed } };

const Dogs = () => { const { data, error } = useQuery(GET_DOGS, { suspend: true }); if (error) { return

Error! {error.message}
; }

return (

    {data.dogs.map(dog => (
  • {dog.breed}
  • ))}
); };

const MyComponent = () => ( Loading...}> );

There are known issues with suspense mode for

useQuery
:
  • only the
    cache-first
    fetch policy is supported (#13)
  • networkStatus
    returned by
    useQuery
    is undefined (#68)

useMutation

import gql from 'graphql-tag';
import { useMutation } from 'react-apollo-hooks';

const TOGGLE_LIKED_PHOTO = gql mutation toggleLikedPhoto($id: String!) { toggleLikedPhoto(id: $id) @client };

const DogWithLikes = ({ url, imageId, isLiked }) => { const [toggleLike, { loading }] = useMutation(TOGGLE_LIKED_PHOTO, { variables: { id: imageId }, }); return (

{isLiked ? 'Stop liking' : 'like'}
); };

The

useMutation
returns a tuple with mutation function first and the result of mutation execution in second. It's a similar signature you might know from official Mutation component and the same behavior as well.

You can provide any mutation options as an argument to the

useMutation
hook or to the function returned by it, e. g.:
function AddTaskForm() {
  const inputRef = useRef();
  const [addTask] = useMutation(ADD_TASK_MUTATION, {
    update: (proxy, mutationResult) => {
      /* your custom update logic */
    },
    variables: {
      text: inputRef.current.value,
    },
  });

return (

Add task ); }

Or:

function TasksWithMutation() {
  const [toggleTask] = useMutation(TOGGLE_TASK_MUTATION);

return ( toggleTask({ variables: { taskId: task.id } })} tasks={data.tasks} /> ); }

useSubscription

If you are just interested in the last subscription value sent by the server (e. g. a global indicator showing how many new messages you have in an instant messenger app) you can use

useSubscription
hook in this form:
const NEW_MESSAGES_COUNT_CHANGED_SUBSCRIPTION = gql`
  subscription onNewMessagesCountChanged($repoFullName: String!) {
    newMessagesCount
  }
`;

const NewMessagesIndicator = () => { const { data, error, loading } = useSubscription( NEW_MESSAGES_COUNT_CHANGED_SUBSCRIPTION );

if (loading) { return

Loading...
; };

if (error) { return

Error! {error.message}
; };

return

{data.newMessagesCount} new messages
; }

For more advanced use cases, e. g. when you'd like to show a notification to the user or modify the Apollo cache (e. g. you'd like to show a new comment on a blog post page for a user visiting it just after it was created) you can use the

onSubscriptionData
callback:
const { data, error, loading } = useSubscription(MY_SUBSCRIPTION, {
  variables: {
    // ...
  },
  onSubscriptionData: ({ client, subscriptionData }) => {
    // Optional callback which provides you access to the new subscription
    // data and the Apollo client. You can use methods of the client to update
    // the Apollo cache:
    // https://www.apollographql.com/docs/react/advanced/caching.html#direct
  }
  // ... rest options
});

In some cases you might want to subscribe only after you have all the information available, eg. only when user has selected necessary filters. Since hooks cannot be used conditionally, it would lead to unnecessary complicated patterns.

Instead, you can use the

skip
option which turns the subsciption dormant until toggled again. It will also unsubscribe if there was any previous subscription active and throw away previous result.

useApolloClient

const MyComponent = () => {
  const client = useApolloClient();
  // now you have access to the Apollo client
};

Testing

An example showing how to test components using react-apollo-hooks: https://github.com/trojanowski/react-apollo-hooks-sample-test

Server-side rendering

react-apollo-hooks supports server-side rendering with the

getMarkupFromTree
function. Example usage:
import express from 'express';
import { ApolloProvider, getMarkupFromTree } from 'react-apollo-hooks';
import { renderToString } from 'react-dom/server';

const HELLO_QUERY = gql query HelloQuery { hello };

function Hello() { const { data } = useQuery(HELLO_QUERY);

return

{data.message}

; }

const app = express();

app.get('/', async (req, res) => { const client = createYourApolloClient(); const renderedHtml = await getMarkupFromTree({ renderFunction: renderToString, tree: ( ), }); res.send(renderedHtml); });

getMarkupFromTree
supports
useQuery
hooks invoked in both suspense and non-suspense mode, but the React.Suspense component is not supported. You can use
unstable_SuspenseSSR
provided by this library instead:
import { unstable_SuspenseSSR as UnstableSuspenseSSR } from 'react-apollo-hooks';

function MyComponent() { return ( }>

); }

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.