フロントエンド開発といえば。
react アプリの初期化( npm init vite@latest <アプリ名> )

tanstack query ( react query ) の使い方

● install

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>,
);

● 2つのコンポーネントを行き来してキャッシュが有効であることを確認する

コンポーネント 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;

● react query + graphql

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 };

・1. GraphQLClient だけで graphql クエリの実行

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
  }, []);

・2. graphql-codegen を使って、型を自動生成し tanstack query + graphql クエリの実行

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),
  });
No.2258
05/15 17:27

edit