0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Query を導入するタイミングはいつ?

0
Posted at

フロントエンド開発で React を使うと、
グローバルステート管理 や データ取得 が悩みの種になりがちです。
シンプルな useEffect だけで API を叩く場合でも、エラー処理やローディング状態、ページネーションが絡むと一気にコードが増え、可読性も下がってしまいます。

そんなとき React Query が “頼れる相棒” になってくれます。この記事では、React Query の特徴と使いどころ、そしてシンプルな useEffect で済ませるケースとの見極め方を紹介します。

React Query が提供する 6 つの強み

  1. 宣言的なデータ取得:useQuery で「どう取るか」より「何を取りたいか」を書くイメージで実装できる
  2. 自動キャッシュ:同じクエリを叩くたびに API を呼ばず、パフォーマンスが向上
  3. リアルタイム更新:キャッシュが更新されると UI も即反映
  4. クエリの無効化:必要に応じてキャッシュを捨てて再フェッチできる
  5. 楽観的 UI 更新:サーバー確認前に UI を更新し、体感速度アップ
  6. ローディング & エラー管理:状態管理用ボイラープレートを大幅に削減

React Query の基本概念 — useQuery と useMutation

useQuery(読み取り)

import { useQuery } from 'react-query';

const ExampleComponent = () => {
  const { data, isLoading, error } = useQuery('exampleQuery', fetchDataFunction);

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

  // Render your component with the fetched data
  return <div>{data}</div>;
};
  • クエリキー:'exampleQuery'
    これがキャッシュの識別子になります。
  • フェッチ関数:fetchDataFunction
    Promise を返す関数なら何でも OK。

useMutation(書き込み)

import { useMutation } from 'react-query';

const ExampleComponent = () => {
  const { mutate } = useMutation('exampleMutation', updateDataFunction);

  const handleClick = () => {
    // Trigger the mutation when a button is clicked
    mutate();
  };

  return <button onClick={handleClick}>Update Data</button>;
};
  • 変更系 API を呼び出すときに使用。
  • 成功後に関連クエリを invalidates して最新データを取得。

React Query の魔法 — カスタムページネーション

API 側で limit / offset などを使う場合、
React QueryfetchNextPagegetNextPageParam が威力を発揮します。

import { useQuery, useQueryClient } from 'react-query';

const LIMIT = 10;

const fetchPaginatedData = async ({ pageParam = 1 }) => {
  const response = await fetch(`/api/data?page=${pageParam}&limit=${LIMIT}`);
  return response.json();
};

const CustomPaginationComponent = () => {
  const queryClient = useQueryClient();

  const { data, fetchNextPage, hasNextPage } = useQuery(
    'paginatedData',
    fetchPaginatedData,
    {
      getNextPageParam: (lastPage, allPages) => {
        // Use the current length of all pages to calculate the next page
        return allPages.length + 1;
      },
    }
  );

  const handleLoadMore = () => {
    fetchNextPage();
  };

  return (
    <div>
      {/* Render your paginated data */}

      {hasNextPage && <button onClick={handleLoadMore}>Load More</button>}
    </div>
  );
};

ポイント

  • fetchPaginatedDatapageParam を受け取り、API に offsetlimit を渡す。
  • getNextPageParam で「次に呼ぶ offset」を計算。
  • hasNextPagetrue なら「もっと見る」ボタンを表示。

これだけで無限スクロールや手動ロードがシンプルに書けます。

React Query を導入すべきか? useEffect で十分か?

React Query を使うメリット

  • 複雑なデータ取得ロジック を簡潔に書ける
  • 自動キャッシュ により通信回数を削減
  • ローディング/エラー/ページネーション の共通処理を省力化
  • リアルタイム更新 で UI 一貫性を保てる

デメリット

  • ライブラリ学習コストが少し発生
  • シンプルな画面には “やり過ぎ” になることも

こんなときは React Query

  • API が複数あり、依存関係 や 再取得 タイミングが複雑
  • ユーザビリティ重視で 楽観的更新 や 無限スクロール が必要
  • コーポレートサイトより SaaS アプリ のような場面

こんなときは useEffect

  • 1 画面 1 回しか呼ばない静的データ
  • 成功・失敗・ローディングだけ分かれば十分

まとめ

React Query は 「書きたいロジック」 に集中させてくれる便利ツールです。
API 通信が増えるにつれ恩恵が大きくなるので、プロジェクトの規模や要件に合わせて導入を検討しましょう。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?