🎶

TanStack Queryで始める宣言的なAPIクエリ実装

2024/08/09に公開

TanStack Queryで始める宣言的なAPIクエリ実装

はじめに

現代のウェブアプリケーション開発において、データの取得と管理は非常に重要な要素です。特に、APIからのデータ取得は、ユーザー体験を向上させるために不可欠です。TanStack Query(旧React Query)は、Reactアプリケーションにおけるデータフェッチングを簡素化し、効率的に管理するための強力なライブラリです。本記事では、TanStack Queryを使用して宣言的なAPIクエリを実装する方法について詳しく解説します。

TanStack Queryは、データの取得、キャッシング、更新、同期を簡単に行うためのツールを提供します。これにより、開発者はデータの状態管理に煩わされることなく、アプリケーションのロジックに集中できます。この記事では、TanStack Queryの基本的な使い方から、実践的な例を通じてその機能を深く掘り下げていきます。

TanStack Queryの全体像

以下のダイアグラムは、TanStack Queryの基本的なフローを示しています。データの取得からキャッシング、エラーハンドリングまでの流れを視覚的に理解するのに役立ちます。

このダイアグラムでは、APIリクエストが行われ、データが取得される過程を示しています。データ取得が成功した場合はキャッシュされ、UIに表示されます。一方、失敗した場合はエラーハンドリングが行われ、適切なメッセージが表示されます。

TanStack Queryの基本概念

1. TanStack Queryとは?

TanStack Queryは、Reactアプリケーションにおけるデータフェッチングのためのライブラリです。主な機能には以下が含まれます。

  • データの取得: APIからデータを簡単に取得できます。これにより、開発者はHTTPリクエストの詳細を気にせず、データの取得に集中できます。TanStack Queryは、Promiseベースの関数を使用してデータを取得し、非同期処理を簡素化します。

  • キャッシング: 取得したデータをキャッシュし、再利用することでパフォーマンスを向上させます。キャッシュは、同じデータを再度取得する際の待機時間を短縮し、ユーザー体験を向上させます。TanStack Queryは、デフォルトでデータをキャッシュし、必要に応じて自動的に再フェッチを行います。

  • 自動再フェッチ: データが変更された場合、自動的に再フェッチを行います。これにより、常に最新のデータを表示することができます。例えば、ユーザーがデータを更新した場合、他のユーザーにもその変更が即座に反映されます。

  • 状態管理: データの状態を簡単に管理できます。ローディング状態やエラー状態を簡単に扱うことができ、UIの状態を適切に反映させることができます。これにより、ユーザーはアプリケーションの状態を直感的に理解できるようになります。

2. 宣言的なAPIクエリ

TanStack Queryは、宣言的なアプローチを採用しています。これは、データの取得や管理をコンポーネントの状態として扱うことを意味します。開発者は、データの取得方法を明示的に指定するだけで、ライブラリが内部で最適な方法でデータを管理します。このアプローチにより、コードがシンプルになり、可読性が向上します。

宣言的なAPIクエリの利点は、アプリケーションの状態を明確に保つことができる点です。例えば、データの取得が成功した場合、ローディングインジケーターを非表示にし、データを表示することができます。これにより、ユーザーはアプリケーションの状態を直感的に理解できるようになります。

TanStack Queryのインストールとセットアップ

1. インストール

TanStack Queryは、npmまたはyarnを使用して簡単にインストールできます。以下のコマンドを実行してください。

npm install @tanstack/react-query

または

yarn add @tanstack/react-query

このインストールにより、TanStack Queryのすべての機能を利用できるようになります。

2. セットアップ

インストールが完了したら、アプリケーションのエントリーポイントでQueryClientを作成し、QueryClientProviderでラップします。これにより、アプリケーション全体でTanStack Queryの機能を利用できるようになります。

import React from 'react';
import ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';

const queryClient = new QueryClient();

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>,
  document.getElementById('root')
);

このコードでは、QueryClientをインスタンス化し、QueryClientProviderでアプリケーションをラップしています。これにより、アプリケーション内のすべてのコンポーネントでTanStack Queryの機能を利用できるようになります。

APIクエリの実装

1. データの取得

TanStack Queryを使用してAPIからデータを取得する基本的な方法を見ていきましょう。以下の例では、JSONPlaceholderというダミーAPIからユーザー情報を取得します。

import React from 'react';
import { useQuery } from '@tanstack/react-query';

const fetchUsers = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/users');
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
};

const Users = () => {
  const { data, error, isLoading } = useQuery(['users'], fetchUsers);

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {data.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

export default Users;

このコードでは、useQueryフックを使用してデータを取得しています。fetchUsers関数はAPIからユーザー情報を取得し、useQueryはその結果を管理します。useQueryは、データの取得、ローディング状態、エラー状態を一元管理し、コンポーネントの状態を簡潔に保つことができます。

2. クエリのオプション

useQueryには、さまざまなオプションを指定できます。例えば、データのキャッシュ時間や再フェッチの条件を設定できます。以下の例では、キャッシュの保持時間を5分に設定し、ウィンドウがフォーカスされたときに再フェッチしないようにしています。

const { data, error, isLoading } = useQuery(['users'], fetchUsers, {
  staleTime: 1000 * 60 * 5, // 5分間キャッシュを保持
  refetchOnWindowFocus: false, // ウィンドウがフォーカスされたときに再フェッチしない
});

このように、オプションを設定することで、アプリケーションの要件に応じたデータ管理が可能になります。特に、staleTimeを設定することで、データが古くなるまでの時間を指定でき、パフォーマンスを最適化できます。

3. データの更新

TanStack Queryを使用すると、データの更新も簡単に行えます。以下の例では、ユーザー情報を更新するためのmutate関数を使用します。

import { useMutation, useQueryClient } from '@tanstack/react-query';

const updateUser = async (userId, userData) => {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`, {
    method: 'PUT',
    body: JSON.stringify(userData),
    headers: {
      'Content-Type': 'application/json',
    },
  });
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
};

const UpdateUser = ({ userId }) => {
  const queryClient = useQueryClient();
  const mutation = useMutation(updateUser, {
    onSuccess: () => {
      // ユーザー情報を再フェッチ
      queryClient.invalidateQueries(['users']);
    },
  });

  const handleUpdate = () => {
    mutation.mutate(userId, { name: 'Updated User' });
  };

  return <button onClick={handleUpdate}>Update User</button>;
};

この例では、useMutationを使用してユーザー情報を更新し、成功した場合にinvalidateQueriesを呼び出してキャッシュを無効化しています。これにより、最新のデータを取得することができます。useMutationは、データの更新や削除などの操作を簡単に行うためのフックで、エラーハンドリングやローディング状態の管理もサポートしています。

TanStack Queryの高度な機能

1. ページネーション

TanStack Queryは、ページネーションを簡単に実装できます。以下の例では、ページネーションを使用してデータを取得します。

const fetchUsers = async (page = 1) => {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users?_page=${page}&_limit=10`);
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
};

const Users = () => {
  const [page, setPage] = React.useState(1);
  const { data, error, isLoading } = useQuery(['users', page], () => fetchUsers(page));

  return (
    <div>
      {isLoading && <div>Loading...</div>}
      {error && <div>Error: {error.message}</div>}
      <ul>
        {data.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
      <button onClick={() => setPage(old => Math.max(old - 1, 1))}>Previous</button>
      <button onClick={() => setPage(old => old + 1)}>Next</button>
    </div>
  );
};

このコードでは、ページ番号を状態として管理し、useQueryのキーにページ番号を含めています。これにより、ページごとに異なるデータを取得できます。ページネーションを実装することで、ユーザーは大量のデータを効率的に閲覧できるようになります。特に、データが多い場合には、ページネーションを使用することで、ユーザーが必要な情報に迅速にアクセスできるようになります。

2. 無限スクロール

無限スクロールもTanStack Queryで簡単に実装できます。以下の例では、無限スクロールを使用してデータを取得します。

import { useInfiniteQuery } from '@tanstack/react-query';

const fetchUsers = async ({ pageParam = 1 }) => {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users?_page=${pageParam}&_limit=10`);
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
};

const Users = () => {
  const {
    data,
    error,
    isLoading,
    fetchNextPage,
    hasNextPage,
  } = useInfiniteQuery(['users'], fetchUsers, {
    getNextPageParam: (lastPage, pages) => {
      return lastPage.length ? pages.length + 1 : undefined;
    },
  });

  return (
    <div>
      {isLoading && <div>Loading...</div>}
      {error && <div>Error: {error.message}</div>}
      <ul>
        {data.pages.map((page) =>
          page.map(user => <li key={user.id}>{user.name}</li>)
        )}
      </ul>
      {hasNextPage && <button onClick={fetchNextPage}>Load More</button>}
    </div>
  );
};

この例では、useInfiniteQueryを使用して無限スクロールを実装しています。getNextPageParam関数を使用して、次のページのパラメータを決定します。無限スクロールを実装することで、ユーザーはスクロールするだけで新しいデータを取得できるようになります。これにより、ユーザーはよりスムーズにデータを閲覧でき、アプリケーションの使い勝手が向上します。

TanStack Queryのベストプラクティス

1. エラーハンドリング

APIからのデータ取得時にエラーが発生することがあります。TanStack Queryでは、エラーハンドリングを簡単に行うことができます。useQueryuseMutationerrorプロパティを使用して、エラー情報を取得し、適切に表示します。エラーメッセージをユーザーにわかりやすく表示することで、ユーザー体験を向上させることができます。

エラーハンドリングの一例として、エラーが発生した場合にリトライ機能を実装することが考えられます。TanStack Queryでは、リトライの回数や間隔を設定することができ、ネットワークの不安定な状況でもユーザーにスムーズな体験を提供できます。

2. キャッシュの管理

TanStack Queryは、デフォルトでデータをキャッシュしますが、キャッシュの管理は重要です。staleTimecacheTimeを適切に設定することで、パフォーマンスを向上させることができます。特に、頻繁に更新されるデータの場合、キャッシュの設定を見直すことが重要です。

キャッシュの管理においては、データの更新頻度やユーザーの利用パターンを考慮することが重要です。例えば、リアルタイム性が求められるデータの場合、staleTimeを短く設定することで、常に最新の情報を提供できます。

3. コンポーネントの分割

データ取得のロジックをコンポーネントから分離することで、再利用性を高めることができます。カスタムフックを作成し、データ取得のロジックをまとめると良いでしょう。これにより、コードの可読性が向上し、メンテナンスが容易になります。

カスタムフックを使用することで、同じデータ取得ロジックを複数のコンポーネントで再利用でき、コードの重複を避けることができます。例えば、ユーザー情報を取得するカスタムフックを作成し、異なるコンポーネントでそのフックを使用することで、コードの一貫性を保つことができます。

まとめ

TanStack Queryは、Reactアプリケーションにおけるデータフェッチングを簡素化し、効率的に管理するための強力なライブラリです。宣言的なAPIクエリの実装を通じて、データの取得、更新、キャッシングを簡単に行うことができます。この記事では、TanStack Queryの基本的な使い方から高度な機能までを詳しく解説しました。

今後のプロジェクトでTanStack Queryを活用することで、データ管理の効率を大幅に向上させることができるでしょう。ぜひ、実際のアプリケーションに取り入れてみてください。

参考文献

GitHubで編集を提案

Discussion