react-fetch-cache-patterns について
多数のAPIリクエストを扱うReactアプリ向けに、データ取得とキャッシュのパターンをまとめたスキルです。リクエストフローやバックエンド負荷、障害処理を改善する開発者向けに、ライブラリ利用時とReact単体の例を用意しています。
主な機能
- 018カテゴリ、48のルール
- 02リクエストのバッチ処理と重複排除
- 03キャッシュ戦略と無効化
- 04バックエンド向け同時実行・再試行制御
- 05プリフェッチと障害耐性のパターン
- 06調整可能なコードテンプレート
活用シーン
- 01Reactのデータ取得時のウォーターフォール削減
- 02フィードやリストによるバックエンド負荷の抑制
- 03キャッシュ、プリフェッチ、再試行の追加
- 04データ取得コードの障害耐性の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill react-fetch-cache-patternsインストール後、Claude Code で/react-fetch-cache-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonassets/templates/_template.mdcarousel-data-loader.template.tsxinfinite-feed.template.tsxprefetch-link.template.tsxrequest-collapser.template.tsuse-resource-query-no-deps.template.tsxuse-resource-query.template.tsxreferences/_sections.mdcache-deterministic-keys.mdcache-normalize-shared-entities.mdcache-select-subscribed-fields.mdcache-set-stale-time.mdcache-shared-key-factory.mdcache-stale-while-revalidate.mdcache-tiered-stale-fresh.mdfeed-bounded-working-set.mdfeed-cursor-pagination.mdfeed-image-lazy-and-sized.mdfeed-multi-carousel-isolation.mdfeed-split-summary-from-detail.mdfeed-stable-keys-across-pages.mdfeed-virtualize-long-lists.mdmutate-cancel-queries-on-mutate.mdmutate-optimistic-updates-with-rollback.mdmutate-set-data-over-invalidate.mdmutate-surgical-invalidation.mdorch-avoid-effect-chains.mdorch-batch-n-plus-one-fanout.md詳細
実験的な React データ取得とキャッシュのベストプラクティス
バックエンドに過剰な負荷をかけずに、多数の API リクエストを取得してキャッシュする React アプリケーションの実装パターンです。8 つのカテゴリにまたがる 48 のルールを、実行ライフサイクルへの影響が大きい順に並べています。前のカテゴリは、その後のすべてのカテゴリに連鎖的に影響します。テンプレートでは、ライブラリを使う実装(TanStack Query、SWR)と、ライブラリを使わない実装(純粋な React + AbortController)の両方を示しており、スタックの制約にかかわらずパターンを活用できます。
適用する場面
fetch、useQuery、useSWR、またはデータ取得フックを呼び出す React コンポーネントを作成またはレビューするとき- 多数の項目を表示し、それぞれの項目でデータ取得が必要なリスト、フィード、カルーセルを設計するとき
- 「バックエンドに過剰な負荷がかかっている」「ページの読み込みが遅い」といった症状を調査するとき
- クライアントサイドでのデータ取得、ルートローダー、サーバーコンポーネント、SSR のいずれを選ぶか検討するとき
- プリフェッチ、リトライ、楽観的更新、または何らかのエラー処理ロジックを実装するとき
- すでにデータ取得を行っているものの、ウォーターフォールやキャッシュ戦略、同時実行数の制限がないコードをリファクタリングするとき
優先度別のルールカテゴリ
| # | カテゴリ | 影響度 | プレフィックス | ルール数 |
|---|---|---|---|---|
| 1 | リクエストのオーケストレーション | CRITICAL | orch- | 7 |
| 2 | キャッシュ戦略 | CRITICAL | cache- | 7 |
| 3 | バックエンドの保護 | CRITICAL | protect- | 7 |
| 4 | プリフェッチとハイドレーション | HIGH | prefetch- | 6 |
| 5 | 障害へのレジリエンス | HIGH | resilience- | 6 |
| 6 | フィードとカルーセルのパターン | MEDIUM-HIGH | feed- | 7 |
| 7 | ミューテーションと無効化 | MEDIUM | mutate- | 4 |
| 8 | コンポーネントのパターン | MEDIUM | render- | 4 |
クイックリファレンス
1. リクエストのオーケストレーション(CRITICAL)
orch-parallelize-independent-fetches— 独立したリクエストにはPromise.allを使い、awaitを逐次実行しないorch-batch-n-plus-one-fanout— DataLoader 形式のバッチ処理で、行ごとのデータ取得をまとめるorch-dedupe-in-flight-requests— キーごとに実行中のリクエストを 1 つにし、購読者間で共有するorch-lift-fetch-to-route-loader— ルートのチャンクのダウンロードと並行してデータを取得するorch-avoid-effect-chains— 依存関係グラフを平坦化し、本当に依存するものだけを待機させるorch-server-fetch-when-possible— クライアントの状態に依存しないデータ取得は、可能であれば RSC/サーバーに移すorch-prefer-bulk-endpoint-for-fanout— N 個の並列リクエストより、1 回の一括リクエストを優先する
2. キャッシュ戦略(CRITICAL)
cache-deterministic-keys— キャッシュキーを正規化し、undefinedを除去して配列をソートするcache-normalize-shared-entities— エンティティはそれぞれ 1 度だけ保存し、ビューからは参照するcache-set-stale-time—staleTimeは更新頻度ではなく、データの変化しやすさに合わせて調整するcache-stale-while-revalidate— 古いデータを即座に表示し、バックグラウンドで再検証するcache-select-subscribed-fields— オブジェクト全体ではなく、その一部を購読するcache-shared-key-factory— キーの信頼できる情報源を型付きで一元化し、読み取りと書き込みの不一致を防ぐcache-tiered-stale-fresh— データクラス(リアルタイム、フレッシュ、ウォーム、コールド、静的)ごとに異なるstaleTimeを設定する
3. バックエンドの保護(重大)
protect-concurrency-limit-fanout—p-limit/セマフォで同時リクエスト数を制限しますprotect-collapse-identical-requests— fetch 層で進行中の重複リクエストを統合しますprotect-debounce-user-driven-fetches— 検索/フィルターリクエストを送信する前に、ユーザーの操作が止まるのを待ちますprotect-throttle-scroll-triggered— ビューポートをトリガーとする fetch には IntersectionObserver を使用しますprotect-jittered-retry-backoff— ランダムなジッターを加えて、リトライ時のサンダリングハードを防ぎますprotect-circuit-breaker— 継続的に失敗するエンドポイントへの呼び出しを、クールダウン期間中停止しますprotect-rate-limit-aware-client—Retry-AfterとX-RateLimit-*ヘッダーに従います
4. プリフェッチとハイドレーション(高)
prefetch-hover-intent-links— ホバー/pointerdown 時にプリフェッチし、即座に遷移できるようにしますprefetch-parallel-loader-queries— ローダー内の独立したクエリを並列化しますprefetch-hydrate-server-cache— サーバーで取得したデータをHydrationBoundary/RSC 経由で送信しますprefetch-idle-likely-next— 次に必要となる可能性が高いデータにはrequestIdleCallbackを使用しますprefetch-viewport-triggered-next-page—rootMarginを使用して次ページのプリフェッチを開始しますprefetch-budget-and-priority— 優先度に応じてプリフェッチを分類し、Save-Dataを尊重します
5. 障害への耐性(高)
resilience-abort-on-unmount—AbortSignalを渡して古くなった fetch をキャンセルしますresilience-bounded-timeouts—AbortSignal.timeout()でエンドポイントごとにタイムアウトを設定しますresilience-scoped-error-boundaries— ページ単位ではなく、データセクションごとにエラーバウンダリーを設けますresilience-stale-fallback— 新しいデータの fetch に失敗した場合、古いキャッシュを表示しますresilience-no-auto-retry-mutations— 冪等性キーを使用するか、自動リトライを行わないようにしますresilience-graceful-degradation— 重要度の異なる「クリティカル」「重要」「装飾」の各層を設け、それぞれ異なる障害時の動作を定義します
6. フィードとカルーセルのパターン(中〜高)
feed-virtualize-long-lists— 50 項目を超えるリストには TanStack Virtual を使用しますfeed-cursor-pagination— 追加項目や大きなオフセットには、オフセット方式よりカーソル方式が適していますfeed-split-summary-from-detail— カルーセルの概要は軽量にし、詳細は必要に応じて取得しますfeed-multi-carousel-isolation— ホームページのフィードでは、カルーセルごとにエラーバウンダリー/Suspense バウンダリーを設け、重要度に応じたフォールバックを用意しますfeed-stable-keys-across-pages— キーにはエンティティ ID を使用し、インデックスは決して使用しませんfeed-image-lazy-and-sized—loading="lazy"と明示的な寸法を指定しますfeed-bounded-working-set— 無制限に増加するフィードには、maxPagesとエンティティ単位の LRU 削除を使用します
7. ミューテーションと無効化(中)
mutate-optimistic-updates-with-rollback— スナップショットを取得し、楽観的に書き込み、エラー時にロールバックしますmutate-surgical-invalidation— ツリー全体ではなく、特定のキーを無効化しますmutate-set-data-over-invalidate— ミューテーションのレスポンスをキャッシュに直接書き込みますmutate-cancel-queries-on-mutate— 楽観的に書き込む前に、実行中のクエリをキャンセルします
8. コンポーネントのパターン(中)
render-stable-query-keys—useMemoでオブジェクトキーの参照を安定させますrender-cap-fanout-in-lists— フェッチ処理を引き上げ、DataLoader でバッチ処理し、仮想化しますrender-suspense-per-section— データセクションごとに Suspense 境界を1つ設けますrender-colocate-fetch-with-consumer—useQueryはルートではなく、利用するコンポーネントの近くに配置します
使用方法
- カテゴリーの定義と影響の根拠については、references/_sections.md を開きます
- 誤ったコードと正しいコードの例については、個々のルールファイルを読みます
- すぐに使えるスキャフォールドについては、スキャフォールディングテンプレートを参照します
- AGENTS.md ナビゲーションドキュメント(自動生成)では、閲覧用の目次を確認できます
スキャフォールディングテンプレート
assets/templates/ に、すぐに応用できるコードテンプレートが6つあります。
| テンプレート | ライブラリの依存関係 | 目的 |
|---|---|---|
use-resource-query.template.tsx | TanStack Query | キーファクトリー、リトライ、アボート、任意のサスペンスに対応した標準クエリフック |
use-resource-query-no-deps.template.tsx | なし(React + AbortController のみ) | 上記と同じパターンを、ライブラリなしで実現します。手作りのキャッシュ、重複排除、ジッター付きリトライ、staleTime/gcTime、同時実行数の上限を含みます |
carousel-data-loader.template.tsx | TanStack Query + react-error-boundary | 単一のカルーセル(概要 + ビューポートをトリガーとする詳細データ)と、カルーセルごとに失敗を分離する複数カルーセルのフィードに対応します |
infinite-feed.template.tsx | TanStack Query + TanStack Virtual | 仮想化と作業セットの上限設定に対応した、カーソルページネーション方式の無限フィード |
prefetch-link.template.tsx | なし | ホバー/インテントによるプリフェッチ用のリンクラッパー |
request-collapser.template.ts | なし | 実行中リクエストの重複排除と同時実行数の上限を実現するユーティリティ |
ライブラリなしでの方法: バンドルに TanStack Query/SWR/DataLoader を追加できない場合(サイズの制約、ホストアプリとの競合、依存関係の禁止など)は、use-resource-query-no-deps.template.tsx から始めてください。React とウェブプラットフォームのみを使い、約250行でキャッシュ/重複排除/リトライ/アボートの基本パターンを実装しています。TanStack に依存する他のテンプレートは、これを基に応用できます。最初から依存関係がないのは、request-collapser と prefetch-link のテンプレートのみです。
参考ファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリーの定義、順序、影響の根拠 |
| assets/templates/_template.md | 新しいルールを作成するためのテンプレート |
| metadata.json | バージョン、参考資料、概要 |
関連スキル
react-optimise— React の描画パフォーマンス全般(このスキルはデータフェッチに特化しています)nextjs-bundle-optimizer— Next.js のバンドル/ペイロード最適化inngest-nextjs-patterns— サーバーサイドのワークフローパターン(サーバーフェッチのガイダンスを補完します)