⚡️ React에서 서버 상태 관리하기: useQuery 활용법
useQuery란?
useQuery는 비동기 데이터(fetching)를 관리하는 훅으로 API 요청을 단순화하고 캐싱, 로딩/에러 상태 관리까지 자동으로 처리해준다.
기존에는 useEffect와 useState의 조합으로 데이터를 불러왔지만 useQuery만 있으면 훨씬 깔끔하게 구현이 가능하다.
useQuery를 사용하기 위해서는 우선 TanStack Query를 설치해야 한다.
npm install @tanstack/react-query
그 후 QueryClientProvider로 앱을 감싸준다.
typescript
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import ReactDOM from "react-dom/client";
import App from "./App";
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);
[기본 사용법]
다음은 카테고리 목록을 호출하기 위한 useQuery 예시이다.
typescript
import { useQuery } from "@tanstack/react-query";
import { categoryService } from "@/services/categoryService";
import { Category } from "@/types/category";
export const useCategories = () => {
return useQuery<Category[]>({
queryKey: ["categories"],
queryFn: () => categoryService.getCategories(),
staleTime: 1000 * 60 * 60 * 24, // 24시간
gcTime: 1000 * 60 * 60 * 24 * 7, // 7일
refetchOnWindowFocus: false,
});
};
useQuery에는 몇가지 주요 옵션들이 존재한다.
- queryKey
캐싱과 리페치를 구분하는 고유 키로 배열 형태를 권장한다.
ex) ["categories"], ["user", userId]
- queryFn
데이터를 가져오는 비동기 함수 (API 호출 함수)
- enabled
true/false 값에 따라 쿼리의 실행 여부를 제어한다. 조건부로 요청해야 할 때 사용한다.
- staleTime
데이터가 신선(fresh)하다고 간주되는 시간(ms)으로 이 시간 동안은 refetch가 일어나지 않고 캐시된 데이터를 그대로 사용한다.
- gcTime
캐시가 메모리에 유지되는 시간(ms)으로 staleTime이 지나도 gcTime동안은 캐시가 남아있으며 다시 같은 쿼리를 호출하면 캐시된 데이터를 즉시 반환한다.
- retry
요청 실패 시 자동 재시도 횟수로 기본값은 3이다.
- refetchOnWindowFocus
브라우저 창을 다시 활성화했을 때 자동으로 refetch할지 여부
이렇게 만든 useCategories 훅을 컴포넌트에서 사용하면 다음과 같다.
typescript
import React from "react";
import { useCategories } from "@/hooks/useCategories";
export default function CategoryList() {
const { data, isLoading, error } = useCategories();
if (isLoading) return <p>카테고리를 불러오는 중입니다.</p>;
if (error) return <p>데이터를 불러오는 데 실패했습니다.</p>;
return (
<ul>
{data?.map((category) => (
<li key={category.id}>{category.name}</li>
))}
</ul>
);
}
useQuery를 호출 시 data, isLoading, error 상태를 얻을 수 있다. 그 후 각각의 상태에 따라 렌더링을 처리한다.
useQuery는 서버 데이터 관리의 복잡성을 크게 줄여준다. 단순히 데이터를 가져오는 것 뿐만 아니라 캐싱, 로딩/에러 상태 관리, 자동 리페치까지 지원하기 때문에 적절히 사용하면 개발 생산성을 크게 높일 수 있다.