@apollo/client を suspense 対応させたライブラリを作った
@apollo/client でも suspense したい!
React18 がでたし、loading, data という関係ともおさらばしたい。でも @apollo/client は suspense に対応してない.....
ちょっと困ったので作りました。
以前作成したライブラリと @apollo/client を併用しています。
ApolloClient.watchQuery
からデータを取得しているので refetchQueries
や useQuery(gql).refetch()
とも連携できてるはずです。
suspense された useQuery を体験する
前準備
yarn add @naporin0624/react-flowder rxjs yarn add graphql @apollo/client
query は長いので畳んでおきます。
import { gql, TypedDocumentNode } from "@apollo/client"; const USER_FIELDS = gql` fragment CoreUserFields on User { login name websiteUrl avatarUrl } `; const sampleQuery: SampleQuery = gql` ${USER_FIELDS} query SampleQuery { search(query: "repo:apollographql/apollo is:issue", type: ISSUE, first: 5) { issueCount nodes { ... on Issue { id number title createdAt } } } user(login: "naporin0624") { ...CoreUserFields } } `;
App.tsx
import React, { useMemo } from "react"; import { useSyncQuery, useApolloReset, } from "@naporin0624/react-flowder/apollo"; const App = () => { const data = useSyncQuery( sampleQuery, useMemo(() => ({ pollInterval: 10000, variables: {} }), []) ); const reset = useApolloReset(); return ( <div> <button onClick={reset}>reset</button> <p style={{ whiteSpace: "pre-wrap" }}>{JSON.stringify(data, null, 2)}</p> </div> ); }; export default memo(App)
index.tsx
import React, { Suspense } from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; import { Provider as DatasourceProvider } from "@naporin0624/react-flowder"; import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client"; const token = import.meta.env.VITE_GITHUB_TOKEN; const client = new ApolloClient({ uri: "https://api.github.com/graphql", headers: { authorization: `Bearer ${token}` }, cache: new InMemoryCache(), }); createRoot(document.getElementById("root")!).render( <React.StrictMode> <ApolloProvider client={client}> <DatasourceProvider> <Suspense fallback={null}> <App /> </Suspense> </DatasourceProvider> </ApolloProvider> </React.StrictMode> );