Apollo Client (React) 触ってみた。 Query編

Apolloのドキュメントを読んだ時のメモ

https://www.apollographql.com/docs/

まずは簡単なgraphQL APIを構築 https://github.com/DaisukeMatsumoto0925/graph_practice

Front Next.ts (codegen) Backend Go (gqlgen)

Apolloの構築

const createApolloClient = () => {
  return new ApolloClient({
    link: new HttpLink({
      uri: 'http://localhost:3000/query',
    }),
    cache: new InMemoryCache(),
  });
 };

const client = createApolloClient()
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  )
}

以上、Reduxの構築に比べると圧倒的コード量の少なさ。

useQuery

https://www.apollographql.com/docs/react/data/queries/

apolloで使えるhooks。 GraphQLのQueryを叩く

以下のようにgaraphQLのAPIを叩いてレスポンスを取得できる。

  const { loading, error, data } = useQuery(QUERY_GQL);

そのほかにも様々なコールバック関数が用意されておりかなり使い勝手が良い。 useEffectやssr等で呼び出す必要すらない。

ちなみに graphql code generator というライブラリを使用すると hooksをラッピングするカスタムhookを作成してくれて、さらに便利。 https://www.graphql-code-generator.com/

cache

useQueryが発火した時fetchされた結果は自動的にキャッシュされる。

Whenever Apollo Client fetches query results from your server, it automatically caches those results locally. This makes subsequent executions of the same query extremely fast.

つまり何もする必要はない。

Polling

指定された時間でuseQueryを定期実行してくれる。

  const { loading, error, data } = useQuery(TASKS_QUERY, {
    pollInterval: 500,
  });

試しにDBを直接更新してみた。 f:id:shikatech:20210703171401p:plain

clientではリロードせずにデータがfetchされた。 f:id:shikatech:20210703171521p:plain

fetch policy

デフォルトでは cache-first が適用されている。

no-cacheにした場合

  const { loading, error, data } = useQuery(TASKS_QUERY, {
    fetchPolicy: "no-cache"
  });

f:id:shikatech:20210703172812p:plain

cacheには保存されていない。 その他のポリシー https://www.apollographql.com/docs/react/data/queries/#supported-fetch-policies

その他

https://www.apollographql.com/docs/react/data/queries/#usequery-api

その他にもたくさんのAPIが用意されている。

onCompleted

Queryが成功した時のコールバック

  const {data, refetch, networkStatus, loading, error} = useTasksQuery({
    onCompleted: (data) => {return console.log("result",data)}
  })

f:id:shikatech:20210703221751p:plain

これはかなり使えそう、コールバックにはfetch後のデータが入ってくるが、 それ以外のdom操作でformの中身をリセットしたり、成功時のポップアップを出す場合など

skip

Queryを実行しないようにする。

  const {data, refetch, networkStatus, loading, error} = useTasksQuery({
    skip: true
  })

ある条件下では発火させたくない時はこれを使うのが良さそう。

refetch

hooksのresult

名前の通りQueryを再発火させる。 ボタンなどに仕込めばレスポンスを容易に再取得できる。

const {refetch} = useTasksQuery()

refetch()

以上が構築〜Query編 次回はmutationを見ていく。