Claude CodeでTanStack Queryを使いこなすデータ取得戦略
TanStack Query(React Query)をClaude Codeで効率的に実装する方法を解説。キャッシュ戦略、楽観的更新、無限スクロールなど実践パターンを紹介します。
TanStack Queryでサーバー状態管理を最適化する
TanStack Query(旧React Query)はサーバー状態の取得・キャッシュ・同期を宣言的に管理するライブラリです。Claude Codeを使えば、複雑なキャッシュ戦略や楽観的更新も素早く実装できます。
基本的なクエリ設計
Claude Codeにデータ取得パターンを依頼しましょう。
> TanStack Queryでユーザー一覧のクエリを作成して。
> ページネーション、検索フィルタ、自動リフレッシュ対応で。
import { useQuery, keepPreviousData } from "@tanstack/react-query";
// クエリキーファクトリー
export const userKeys = {
all: ["users"] as const,
lists: () => [...userKeys.all, "list"] as const,
list: (filters: UserFilters) => [...userKeys.lists(), filters] as const,
details: () => [...userKeys.all, "detail"] as const,
detail: (id: string) => [...userKeys.details(), id] as const,
};
interface UserFilters {
page: number;
perPage: number;
search?: string;
role?: string;
}
export function useUsers(filters: UserFilters) {
return useQuery({
queryKey: userKeys.list(filters),
queryFn: () => fetchUsers(filters),
placeholderData: keepPreviousData,
staleTime: 5 * 60 * 1000, // 5分間はキャッシュを使用
refetchOnWindowFocus: true,
});
}
export function useUser(id: string) {
return useQuery({
queryKey: userKeys.detail(id),
queryFn: () => fetchUser(id),
enabled: !!id,
staleTime: 10 * 60 * 1000,
});
}
楽観的更新の実装
ミューテーションと楽観的更新のパターンをClaude Codeに生成してもらいます。
import { useMutation, useQueryClient } from "@tanstack/react-query";
export function useUpdateUser() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: { id: string; updates: Partial<User> }) =>
updateUser(data.id, data.updates),
onMutate: async ({ id, updates }) => {
// 進行中のクエリをキャンセル
await queryClient.cancelQueries({ queryKey: userKeys.detail(id) });
// 現在のデータをバックアップ
const previousUser = queryClient.getQueryData(userKeys.detail(id));
// キャッシュを楽観的に更新
queryClient.setQueryData(userKeys.detail(id), (old: User) => ({
...old,
...updates,
}));
return { previousUser };
},
onError: (_err, { id }, context) => {
// エラー時にロールバック
if (context?.previousUser) {
queryClient.setQueryData(userKeys.detail(id), context.previousUser);
}
},
onSettled: (_data, _error, { id }) => {
// 成功・失敗に関わらず再取得
queryClient.invalidateQueries({ queryKey: userKeys.detail(id) });
queryClient.invalidateQueries({ queryKey: userKeys.lists() });
},
});
}
無限スクロールの実装
useInfiniteQueryを使った無限スクロールもClaude Codeで素早く実装できます。
import { useInfiniteQuery } from "@tanstack/react-query";
export function useInfiniteUsers(search?: string) {
return useInfiniteQuery({
queryKey: ["users", "infinite", { search }],
queryFn: ({ pageParam }) =>
fetchUsers({ page: pageParam, perPage: 20, search }),
initialPageParam: 1,
getNextPageParam: (lastPage) =>
lastPage.hasNext ? lastPage.page + 1 : undefined,
getPreviousPageParam: (firstPage) =>
firstPage.hasPrev ? firstPage.page - 1 : undefined,
});
}
function UserInfiniteList() {
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteUsers();
const users = data?.pages.flatMap((page) => page.users) ?? [];
return (
<div>
{users.map((user) => (
<UserCard key={user.id} user={user} />
))}
{hasNextPage && (
<button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
{isFetchingNextPage ? "読み込み中..." : "もっと見る"}
</button>
)}
</div>
);
}
プリフェッチとSSR対応
Next.jsなどでのサーバーサイドプリフェッチも実装できます。
import { QueryClient, dehydrate, HydrationBoundary } from "@tanstack/react-query";
export async function getServerSideProps() {
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryKey: userKeys.list({ page: 1, perPage: 20 }),
queryFn: () => fetchUsers({ page: 1, perPage: 20 }),
});
return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
}
export default function UsersPage({
dehydratedState,
}: {
dehydratedState: unknown;
}) {
return (
<HydrationBoundary state={dehydratedState}>
<UserList />
</HydrationBoundary>
);
}
カスタムクエリフックのパターン
実務では再利用可能なカスタムフックとして設計します。
function useOptimisticDelete<T extends { id: string }>(
queryKey: readonly unknown[],
deleteFn: (id: string) => Promise<void>
) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: deleteFn,
onMutate: async (id) => {
await queryClient.cancelQueries({ queryKey });
const previous = queryClient.getQueryData(queryKey);
queryClient.setQueryData(queryKey, (old: T[] | undefined) =>
old?.filter((item) => item.id !== id)
);
return { previous };
},
onError: (_err, _id, context) => {
queryClient.setQueryData(queryKey, context?.previous);
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey });
},
});
}
まとめ
TanStack Queryはサーバー状態管理の複雑さを大幅に軽減してくれます。Claude Codeを活用すれば、クエリキー設計、楽観的更新、無限スクロールなどの複雑なパターンも短時間で実装可能です。
状態管理の全体設計はZustand状態管理ガイドを、APIの型安全性はtRPC型安全API開発を参照してください。TanStack Query公式ドキュメントも確認しておきましょう。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
現役DX室長|Claude Code でゼロから多言語AI技術メディア運営中。実務直結の自動化、AI開発相談・研修受付中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Codeで多言語記事を毎日公開するための7つのデプロイ前チェック
日本語だけ公開して終わらせないために、Claude Codeで多言語記事を毎日出す前に確認したい7つのチェックを実例つきで整理しました。
Codex AutomationsでAIに毎日のコンテンツ運用を任せる方法
Codex Automationsを使って、アクセス確認、記事改善、CTA改善、デプロイ、公開確認までを毎日の運用フローとして回す方法を解説します。
Claude Code × GCP Cloud Functions 完全ガイド|サーバーレス関数を爆速開発
GCP Cloud FunctionsをClaude Codeで効率化。HTTP/Pub/Sub/Firestoreトリガーの実装からローカルテスト・デプロイ自動化まで、Masaの実務経験をもとに実例コードで解説。