Skip to content

React QueryにおけるstaleTimeとcacheTimeの違い

React Queryでデータキャッシュを適切に設定するためには、staleTimecacheTimeの概念を理解することが重要です。この記事では、両者の違いと実用的な使用方法について詳しく解説します。

問題の理解

多くの開発者が抱える疑問:

  • APIから取得したデータを最初の取得から2分間キャッシュしたい
  • コンポーネントのマウント/アンマウントに関わらず、2分間はAPIコールを発生させたくない
  • 単純に両方の設定を2分間にしても期待通りに動作しない

staleTimeとcacheTimeの基本概念

staleTime: データの鮮度を管理

staleTimeは「データがどれだけ新鮮か」を制御します。HTTPのCache-Control: max-age=120に似た概念です。

javascript
const query = useQuery(
  ["getUserList"], 
  getUserList, 
  {
    staleTime: 120000, // 2分間は新鮮とみなす
  }
);

staleTimeを120000(2分)に設定すると:

  • 最初の成功したAPIリクエストから2分間は追加のネットワークリクエストが発生しない
  • この期間中は常にキャッシュからデータが読み込まれる
  • データは「新鮮(fresh)」な状態と見なされる

cacheTime: ガベージコレクションのタイミング

cacheTimeは「未使用のデータをキャッシュに保持する時間」を制御します。使用されていないクエリがガベージコレクションされるまでの時間です。

javascript
const query = useQuery(
  ["getUserList"], 
  getUserList, 
  {
    cacheTime: 120000, // 2分間キャッシュを保持
  }
);

cacheTimeの特徴:

  • アクティブなクエリには影響しない(アクティブなクエリは常にキャッシュに残る)
  • 全てのコンポーネントがアンマウントされ、クエリが非アクティブになった時点でカウントダウンが開始
  • デフォルトは5分間

データ取得の二段階プロセス

React Queryの動作を理解するためのメンタルモデル:

ステップ1: 可能な限り高速な応答

React Queryはまずキャッシュをチェックし、有効なデータがあれば即座に返します。キャッシュがない場合のみAPIコールを実行します。

ステップ2: データの鮮度確認

データを返した後、React QueryはstaleTimeに基づいてデータの鮮度を確認します。データが古くなっている(stale)場合は、バックグラウンドでの再取得が行われます。

実践的な設定例

ケース1: 2分間APIコールを防ぎたい場合

javascript
const query = useQuery(
  ["getUserList"], 
  getUserList, 
  {
    staleTime: 120000, // 2分間は新鮮な状態を維持
    cacheTime: 300000, // 5分間キャッシュを保持(デフォルト値)
  }
);

TIP

staleTimeのみを設定すれば、2分間は追加のAPIコールが発生しません。cacheTimeはガベージコレクション用なので、この目的には直接関係しません。

ケース2: 2分ごとに自動再取得したい場合

データが古くなった後、定期的に再取得したい場合はrefetchIntervalを使用します:

javascript
const query = useQuery(
  ["getUserList"], 
  getUserList, 
  {
    staleTime: 0, // 即座に古いとみなす
    refetchInterval: 120000, // 2分ごとに再取得
  }
);

よくある間違いと解決策

誤解1: staleTime経過後即座に再取得される

staleTimeが経過するとデータは「古い」とマークされますが、即座に再取得が行われるわけではありません。再取得は以下の条件で発生します:

  • クエリの再マウント
  • ウィンドウのフォーカス
  • ネット接続の回復
  • refetchIntervalの設定

誤解2: cacheTimeがAPIコール頻度を制御する

cacheTimeはあくまで「未使用データの保持期間」であり、APIコールの頻度には直接関係しません。アクティブなクエリはcacheTimeの設定に関わらずキャッシュに保持されます。

ベストプラクティス

  1. デフォルト値の理解:

    • staleTime: 0(即座に古くなる)
    • cacheTime: 5分(300000ミリ秒)
  2. 用途に応じた設定:

    • ほとんど変化しないデータ: 長いstaleTimeを設定
    • 頻繁に変化するデータ: 短いstaleTimeまたはrefetchIntervalを設定
    • メモリ使用量を最適化: 短いcacheTimeを設定
  3. グローバル設定の活用:

javascript
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000, // 5分
      cacheTime: 10 * 60 * 1000, // 10分
    },
  },
});

まとめ

  • staleTime: データの鮮度を制御。この期間中は追加のAPIコールが発生しない
  • cacheTime: 未使用データのキャッシュ保持時間を制御。ガベージコレクションのタイミング
  • 2分間APIコールを防ぎたい場合はstaleTime: 120000を設定
  • 定期的な再取得にはrefetchIntervalを使用

適切に設定することで、不要なネットワークリクエストを減らし、ユーザーエクスペリエンスを向上させることができます。