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공식 문서도 확인해 두세요.
Related Posts
Claude Code로 리팩토링을 자동화하는 방법
Claude Code를 활용해 코드 리팩토링을 효율적으로 자동화하는 방법을 알아봅니다. 실전 프롬프트와 구체적인 리팩토링 패턴을 소개합니다.
Claude Code로 사이드 프로젝트 개발 속도를 극대화하는 방법 [예제 포함]
Claude Code를 활용해 개인 프로젝트 개발 속도를 획기적으로 높이는 방법을 알아봅니다. 실전 예제와 아이디어부터 배포까지의 워크플로를 포함합니다.
Complete CORS Configuration Guide: Claude Code 활용 가이드
complete cors configuration guide: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.