TanStack Query: Claude Code 활용 가이드
tanstack 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 ? "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 });
},
});
}
정리
TanStack Queryは서버状態관리の複雑さを大幅に軽減してくれます。Claude Codeを활용すれば、쿼리キー설계、楽観的업데이트、無限스크롤などの複雑なパターンも短시간で구현가능합니다。
状態관리の全体설계はZustand状態관리가이드を、APIの타입安全性はtRPC타입安全API개발를 참고하세요.TanStack Query공식 문서도 확인해 두세요.
Claude Code 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code로 리팩토링을 자동화하는 방법
Claude Code를 활용해 코드 리팩토링을 효율적으로 자동화하는 방법을 알아봅니다. 실전 프롬프트와 구체적인 리팩토링 패턴을 소개합니다.
Claude Code로 사이드 프로젝트 개발 속도를 극대화하는 방법 [예제 포함]
Claude Code를 활용해 개인 프로젝트 개발 속도를 획기적으로 높이는 방법을 알아봅니다. 실전 예제와 아이디어부터 배포까지의 워크플로를 포함합니다.
Complete CORS Configuration Guide: Claude Code 활용 가이드
complete cors configuration guide: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.