tanstack-query について
非同期のサーバー状態を扱うアプリ開発者向けの TanStack Query スキルです。クエリ、ミューテーション、キャッシュ、移行のパターンと実装上の注意点を解説します。
主な機能
- 01クエリとミューテーションのパターン
- 02キャッシュの無効化と更新
- 03無限クエリとページネーション
- 04オフラインと永続化のガイド
- 05v5 移行リファレンス
活用シーン
- 01無限スクロールのデータ表示を構築
- 02ミューテーション後のキャッシュ更新を調整
- 03アプリのオフラインデータを処理
- 04プロジェクトを v4 から v5 へ移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill tanstack-queryインストール後、Claude Code で/tanstack-queryを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/basic-patterns.mdcaching-coordination.mdcaching.mddata-transformations.mderror-handling.mdinfinite-queries.mdknown-issues.mdmutations.mdoffline-mode.mdperformance.mdquery-keys.mdssr-hydration.mdtesting.mdtypescript-patterns.mdwebsocket-integration.md詳細
TanStack Query
概要
TanStack Query はデータ取得ライブラリではなく、非同期状態マネージャーです。Promise を返す queryFn を指定すると、React Query がキャッシュ、重複排除、バックグラウンド更新、古いデータの管理を処理します。
使用する場合: 無限スクロール、オフラインファーストのアプリ、フォーカス復帰時や再接続時の自動再取得、複雑なキャッシュ無効化、React Native、サーバーとクライアントを組み合わせたアプリ。
使用しない場合: 純粋な同期状態(useState/Zustand を使用)、正規化された GraphQL キャッシュ(Apollo/urql)、サーバーコンポーネントのみのアプリ(ネイティブの fetch)、単純な取得と表示(サーバーコンポーネント)。
クイックリファレンス
| パターン | API | 主なポイント |
|---|---|---|
| 基本的なクエリ | useQuery({ queryKey, queryFn }) | queryKey にパラメーターを含める |
| Suspense クエリ | useSuspenseQuery(options) | enabled オプションは指定できません |
| 並列クエリ | useQueries({ queries, combine }) | 動的な並列データ取得 |
| 依存クエリ | useQuery({ enabled: !!dep }) | 前提となるデータを待機 |
| クエリオプション | queryOptions({ queryKey, queryFn }) | 再利用可能で型安全な設定 |
| 基本的なミューテーション | useMutation({ mutationFn, onSuccess }) | 成功時に無効化 |
| ミューテーションの状態 | useMutationState({ filters, select }) | コンポーネント間でミューテーションを追跡 |
| 楽観的更新 | onMutate -> cancel -> snapshot -> set | onError でロールバック |
| 無限クエリ | useInfiniteQuery({ initialPageParam }) | v5 では initialPageParam が必須 |
| プリフェッチ | queryClient.prefetchQuery(options) | ホバー時や操作意図に応じて事前読み込み |
| 無効化 | queryClient.invalidateQueries({ queryKey }) | デフォルトでは部分一致し、アクティブなもののみ対象 |
| キャンセル | queryFn: ({ signal }) => fetch(url, { signal }) | キー変更時に自動キャンセル |
| select による変換 | select: (data) => data.filter(...) | 構造共有が維持されます |
| スキップトークン | queryFn: id ? () => fetch(id) : skipToken | 型安全な条件付き無効化 |
| 直列ミューテーション | useMutation({ scope: { id } }) | 同じスコープ ID のミューテーションは直列に実行 |
v5 移行クイックリファレンス
| v4(削除) | v5(代わりに使用) |
|---|---|
useQuery(key, fn, opts) | useQuery({ queryKey, queryFn, ...opts }) |
cacheTime | gcTime |
isLoading(データなし) | isPending |
keepPreviousData: true | placeholderData: keepPreviousData |
クエリの onSuccess/onError | useEffect またはミューテーションのコールバック |
useErrorBoundary | throwOnError |
initialPageParam なし | initialPageParam が必須 |
エラー型 unknown | エラー型のデフォルトは Error |
よくある間違い
| 間違い | 正しいパターン |
|---|---|
data の前に isPending を確認する | データ優先:data → error → isPending の順に確認する |
サーバーの状態をローカルの useState にコピーする | データを直接使うか、派生状態のパターンを使う |
コンポーネント内で QueryClient を作成する | コンポーネントの外で一度だけ作成するか、useState を使う |
パラメーターの変更に refetch() を使う | パラメーターを queryKey に含め、自動再取得に任せる |
useQuery と useInfiniteQuery で同じキーを使う | 異なるキーセグメントを使う(キャッシュ構造が異なるため) |
メモ化せずにインラインで select を使う | 安定した関数に切り出すか、useCallback を使う |
再スローせずに catch を使う | queryFn 内でエラーをスローする(fetch は 4xx/5xx で reject されないため) |
useQuery に手動でジェネリクスを指定する | queryFn の戻り値に型を指定し、型推論に任せる |
| 型の絞り込みにクエリを分割代入する | 適切な型の絞り込みのため、クエリオブジェクトをそのまま保持する |
useSuspenseQuery で enabled を使う | 条件付きレンダリングでコンポーネントをマウント/アンマウントする |
| SSR 用のプリフェッチを await しない | ハイドレーションの不一致を避けるため、prefetchQuery を await する |
invalidateQueries ですべてが再取得されない | 非アクティブなクエリには refetchType: 'all' を使う |
委任
- クエリパターンの調査:
Exploreエージェントを使います - キャッシュ戦略のレビュー:
Taskエージェントを使います - コードレビュー:
code-reviewerエージェントに委任します
tanstack-routerスキルが利用可能な場合は、ルートローダーとプリロードのパターンを委任します。tanstack-formスキルが利用可能な場合は、フォーム送信とミューテーションの連携を委任します。tanstack-tableスキルが利用可能な場合は、サーバーサイドのテーブルパターンを委任します。tanstack-startスキルが利用可能な場合は、サーバー関数と SSR データ読み込みを委任します。tanstack-devtoolsスキルが利用可能な場合は、クエリキャッシュのデバッグと確認を委任します。tanstack-dbスキルが利用可能な場合は、リアクティブなクライアントサイドデータベースとライブクエリのパターンを委任します。tanstack-virtualスキルが利用可能な場合は、リストの仮想化と無限スクロールのレンダリングを委任します。tanstack-storeスキルが利用可能な場合は、クライアントサイドで共有するリアクティブな状態管理を委任します。electricsqlスキルが利用可能な場合は、ElectricSQL によるリアルタイムの Postgres 同期パターンを委任します。local-firstスキルが利用可能な場合は、ローカルファーストのアーキテクチャに関する判断と同期エンジンの選定を委任します。
参考資料
- 基本パターン、アーキテクチャ、クエリのバリエーション
- クエリキーとファクトリーパターン
- ミューテーション、楽観的更新、MutationCache
- キャッシュ操作、staleTime と gcTime の違い、シーディング
- データ変換と select のパターン
- レンダートラッキングと構造共有によるパフォーマンス最適化
- エラー処理の戦略
- 無限クエリとページネーション
- オフラインモードと永続化
- WebSocket とリアルタイム連携
- SSR とハイドレーションのパターン
- TypeScript のパターン
- MSW と React Testing Library を使ったテスト
- 既知の v5 の問題と回避策
- Router とのキャッシュ連携 — 単一ソースのキャッシュ戦略、Router キャッシュの無効化、連携した設定