React QueryにおけるstaleTimeとcacheTimeの違い
React Queryでデータキャッシュを適切に設定するためには、staleTime
とcacheTime
の概念を理解することが重要です。この記事では、両者の違いと実用的な使用方法について詳しく解説します。
問題の理解
多くの開発者が抱える疑問:
- APIから取得したデータを最初の取得から2分間キャッシュしたい
- コンポーネントのマウント/アンマウントに関わらず、2分間はAPIコールを発生させたくない
- 単純に両方の設定を2分間にしても期待通りに動作しない
staleTimeとcacheTimeの基本概念
staleTime: データの鮮度を管理
staleTime
は「データがどれだけ新鮮か」を制御します。HTTPのCache-Control: max-age=120
に似た概念です。
const query = useQuery(
["getUserList"],
getUserList,
{
staleTime: 120000, // 2分間は新鮮とみなす
}
);
staleTime
を120000(2分)に設定すると:
- 最初の成功したAPIリクエストから2分間は追加のネットワークリクエストが発生しない
- この期間中は常にキャッシュからデータが読み込まれる
- データは「新鮮(fresh)」な状態と見なされる
cacheTime: ガベージコレクションのタイミング
cacheTime
は「未使用のデータをキャッシュに保持する時間」を制御します。使用されていないクエリがガベージコレクションされるまでの時間です。
const query = useQuery(
["getUserList"],
getUserList,
{
cacheTime: 120000, // 2分間キャッシュを保持
}
);
cacheTime
の特徴:
- アクティブなクエリには影響しない(アクティブなクエリは常にキャッシュに残る)
- 全てのコンポーネントがアンマウントされ、クエリが非アクティブになった時点でカウントダウンが開始
- デフォルトは5分間
データ取得の二段階プロセス
React Queryの動作を理解するためのメンタルモデル:
ステップ1: 可能な限り高速な応答
React Queryはまずキャッシュをチェックし、有効なデータがあれば即座に返します。キャッシュがない場合のみAPIコールを実行します。
ステップ2: データの鮮度確認
データを返した後、React QueryはstaleTime
に基づいてデータの鮮度を確認します。データが古くなっている(stale)場合は、バックグラウンドでの再取得が行われます。
実践的な設定例
ケース1: 2分間APIコールを防ぎたい場合
const query = useQuery(
["getUserList"],
getUserList,
{
staleTime: 120000, // 2分間は新鮮な状態を維持
cacheTime: 300000, // 5分間キャッシュを保持(デフォルト値)
}
);
TIP
staleTime
のみを設定すれば、2分間は追加のAPIコールが発生しません。cacheTime
はガベージコレクション用なので、この目的には直接関係しません。
ケース2: 2分ごとに自動再取得したい場合
データが古くなった後、定期的に再取得したい場合はrefetchInterval
を使用します:
const query = useQuery(
["getUserList"],
getUserList,
{
staleTime: 0, // 即座に古いとみなす
refetchInterval: 120000, // 2分ごとに再取得
}
);
よくある間違いと解決策
誤解1: staleTime経過後即座に再取得される
staleTime
が経過するとデータは「古い」とマークされますが、即座に再取得が行われるわけではありません。再取得は以下の条件で発生します:
- クエリの再マウント
- ウィンドウのフォーカス
- ネット接続の回復
refetchInterval
の設定
誤解2: cacheTimeがAPIコール頻度を制御する
cacheTime
はあくまで「未使用データの保持期間」であり、APIコールの頻度には直接関係しません。アクティブなクエリはcacheTime
の設定に関わらずキャッシュに保持されます。
ベストプラクティス
デフォルト値の理解:
staleTime
: 0(即座に古くなる)cacheTime
: 5分(300000ミリ秒)
用途に応じた設定:
- ほとんど変化しないデータ: 長い
staleTime
を設定 - 頻繁に変化するデータ: 短い
staleTime
またはrefetchInterval
を設定 - メモリ使用量を最適化: 短い
cacheTime
を設定
- ほとんど変化しないデータ: 長い
グローバル設定の活用:
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5分
cacheTime: 10 * 60 * 1000, // 10分
},
},
});
まとめ
staleTime
: データの鮮度を制御。この期間中は追加のAPIコールが発生しないcacheTime
: 未使用データのキャッシュ保持時間を制御。ガベージコレクションのタイミング- 2分間APIコールを防ぎたい場合は
staleTime: 120000
を設定 - 定期的な再取得には
refetchInterval
を使用
適切に設定することで、不要なネットワークリクエストを減らし、ユーザーエクスペリエンスを向上させることができます。