yarn add @tanstack/react-query
yarn add axios
yarn add @types/axios
( nextjs の場合 ) pages/_app.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
export default function App({ Component, pageProps }: AppProps) {
return (
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
</QueryClientProvider>
);
}
( react の場合) src/main.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>,
);
コンポーネント Aaa.tsx の例
(jsonplaceholder から取得してみます)
pages/aaa.tsx
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const Aaa = () => {
const router = useRouter();
const { data, isLoading, isError } = useQuery(['todos', 1], async () => {
const { data } = await axios.get(
'https://jsonplaceholder.typicode.com/todos/1'
);
await new Promise((resolve) => setTimeout(resolve, 3000));
return data;
});
return (
<div>
<Link href="/bbb">bbbへ画面遷移</Link>
<h1>Aaa</h1>
{isLoading && <div>loading...</div>}
{data && <div>title: {data.title}</div>}
</div>
);
};
export default Aaa;
コンポーネント Bbb.tsx の例 pages/bbb.tsx
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const Bbb = () => {
const router = useRouter();
const { data, isLoading, isError } = useQuery(['todos', 1], async () => {
const { data } = await axios.get(
'https://jsonplaceholder.typicode.com/todos/1'
);
await new Promise((resolve) => setTimeout(resolve, 3000));
return data;
});
return (
<div>
<Link href="/aaa">aaaへ画面遷移</Link>
<h1>Bbb</h1>
{isLoading && <div>loading...</div>}
{data && <div>title: {data.title}</div>}
</div>
);
};
export default Bbb;
npm i graphql-request
カスタムした graphqlクライアントを作成しておきます
src/graphqlClient.ts (この例では、ローカルストレージに保存されたjwtトークンを送信しています)
import { GraphQLClient } from "graphql-request";
const createGraphqlClientWithToken = () => {
const baseUrl = process.env.NEXT_PUBLIC_APP_API_BASE_URL;
if (baseUrl === undefined)
throw new Error("axiosClient: APP_API_URL is undefined");
const token =
typeof window !== "undefined" ? localStorage.getItem("idToken") : "";
return new GraphQLClient(baseUrl + "/graphql", {
headers: {
Authorization: `Bearer ${token}`,
},
});
};
export { createGraphqlClientWithToken };
import { GraphQLClient, gql } from "graphql-request";
const graphQLClient = createGraphqlClientWithToken()
const getDataAsync = async () => {
const data = await graphQLClient.request(FindOrCreateUserQueryDocument);
};
useEffect(() => {
getDataAsync();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
codegen.ts
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
overwrite: true,
schema: "http://localhost:4000/graphql",
documents: "../MY-SAMPLE-APP-api/src/query.gql",
generates: {
"src/graphql/generated.ts": {
plugins: [
{
add: {
content: "// Code generated by graphql-codegen. DO NOT EDIT.",
},
},
{
add: {
content: "// @ts-nocheck",
},
},
"typescript",
"typescript-operations",
"typescript-react-query",
],
config: {
fetcher: "graphql-request",
},
},
},
};
export default config;
自動生成の実行
graphql-codegen --config codegen.ts
src/graphql/generated.ts に ファイルが自動生成されるので、それを呼び出します。
コンポーネントで以下のように記述します
import { createGraphqlClientWithToken } from "@/graphqlClient";
import { useQuery } from "@tanstack/react-query";
import {FindOrCreateUserQuery,FindOrCreateUserDocument} from "@/graphql/generated";
const graphQLClient = createGraphqlClientWithToken();
const { data, error, isLoading } = useQuery({
queryKey: ["FindOrCreateUserQueryDocument"],
queryFn: async () =>
graphQLClient.request<FindOrCreateUserQuery>(FindOrCreateUserDocument),
});