TanStack Query 활용

김덕진·2025년 6월 7일

React

목록 보기
10/13

핵심 개념: QueryClient

QueryClient는 TanStack Query의 핵심 객체로, 전체 쿼리와 캐시의 중심 컨트롤러 역할을 합니다. 모든 쿼리 요청, 캐싱 전략, 무효화 등을 여기서 제어합니다.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

<QueryClientProvider client={queryClient}>
  <App />
</QueryClientProvider>

🚨 QueryClientProvider로 감싸지 않으면 useQuery, useMutation 등을 사용할 수 없습니다.

🚨 매 렌더링마다 새로 생성되면 캐싱 무의미하므로 반드시 컴포넌트 외부 혹은 최상단에서 한 번만 생성해야 합니다.


✅ 2. useQuery: 데이터 가져오기 핵심 Hook

import { useQuery } from '@tanstack/react-query';

const { data, isLoading, error } = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodos,
});
  • queryKey: 쿼리를 구분하는 고유 키 (배열 권장)
  • queryFn: 실제로 서버에서 데이터를 fetch하는 함수

🎯 주요 옵션들

  • staleTime: 캐시된 데이터를 오래 유지할 시간
  • cacheTime: 캐시 데이터를 메모리에 유지할 시간 (GC)
  • refetchOnWindowFocus: true면 창 포커스 시 자동 refetch
  • enabled: false로 두면 조건부로 쿼리 실행 가능
useQuery({
  queryKey: ['user', userId],
  queryFn: () => fetchUser(userId),
  enabled: !!userId,
});

enabled는 사용자 ID가 있을 때만 쿼리를 실행하고 싶을 때 유용합니다.


✅ 3. useMutation: POST/PUT/DELETE와 같은 쓰기 작업

import { useMutation, useQueryClient } from '@tanstack/react-query';

const queryClient = useQueryClient();

const mutation = useMutation({
  mutationFn: postTodo,
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['todos'] });
  },
});

mutation.mutate(newTodo);
  • mutationFn: 서버에 데이터를 보내는 함수
  • onSuccess: 성공 시 실행 (주로 쿼리 무효화)
  • onError, onSettled 등도 제공

⚠️ 주의점

mutate는 동기처럼 보이지만 내부적으로 비동기입니다. .then() 체이닝은 mutateAsync를 사용해야 합니다.

await mutation.mutateAsync(newTodo);

✅ 4. isLoading, isFetching, isError 차이점 정리

상태설명
isLoading쿼리가 처음 실행될 때 true
isFetching백그라운드에서 refetch 중일 때 true
isError쿼리 실행 결과 에러가 발생했을 때 true

isLoading은 초기 로딩에만 true, 이후 refetch에는 isFetching이 true입니다.


✅ 5. SSR을 위한 Prefetch 전략

서버에서 데이터를 미리 가져와 클라이언트에게 HTML과 데이터를 함께 전달하려면 dehydrateHydrationBoundary를 활용합니다.

// server-side
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
  queryKey: ['posts'],
  queryFn: fetchPosts,
});

const dehydratedState = dehydrate(queryClient);

return {
  props: {
    dehydratedState,
  },
};
// client-side
import { HydrationBoundary, QueryClientProvider } from '@tanstack/react-query';

<QueryClientProvider client={queryClient}>
  <HydrationBoundary state={dehydratedState}>
    <App />
  </HydrationBoundary>
</QueryClientProvider>

서버에서 미리 데이터를 가져오고, 클라이언트는 이를 재사용하여 초기 렌더링 시 로딩 없이 표시됩니다.


✅ 마무리

TanStack Query는 서버 상태를 위한 강력한 도구입니다. 캐싱, 자동 리페치, 에러 처리, SSR까지 유연하게 대응할 수 있습니다. 다양한 옵션을 적극 활용해 불필요한 로딩을 줄이고, 사용자 경험을 높이는 데 집중하는 것이 핵심입니다.

profile
FrontEnd Developer

0개의 댓글