TanStack Query with Claude Code
Learn about tanstack query using Claude Code. Practical tips and code examples included.
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 ? "Loading..." : "もっと見る"}
</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 });
},
});
}
Zusammenfassung
TanStack Queryはサーバー状態管理の複雑さを大幅に軽減してくれます。Claude Codeを活用すれば、クエリキー設計、楽観的更新、無限スクロールなどの複雑なパターンも短時間で実装可能です。
状態管理の全体設計はZustand状態管理ガイドを、APIの型安全性はtRPC型安全API開発を参照してください。TanStack Query公式ドキュメントも確認しておきましょう。
Related Posts
So beschleunigen Sie Ihre Nebenprojekte mit Claude Code [Mit Beispielen]
Erfahren Sie, wie Sie persönliche Entwicklungsprojekte mit Claude Code drastisch beschleunigen. Inklusive realer Beispiele und eines praktischen Workflows von der Idee bis zum Deployment.
So automatisieren Sie Refactoring mit Claude Code
Erfahren Sie, wie Sie Code-Refactoring mit Claude Code effizient automatisieren. Inklusive praktischer Prompts und konkreter Refactoring-Muster für reale Projekte.
Vollständiger CORS-Konfigurationsleitfaden mit Claude Code
Erfahren Sie alles über die CORS-Konfiguration mit Claude Code. Mit praktischen Tipps und Codebeispielen.