• ABOUT
  • PORTFOLIO
  • POSTS
  • GUESTBOOK

© 2025 BlueCool12 All rights reserved.

2025.09.10React

⚡️ React에서 서버 상태 관리하기: useQuery 활용법

1. useQuery란?

useQuery는 비동기 데이터를 관리하는 훅으로 API 요청을 단순화하고 캐싱, 로딩/에러 상태 관리까지 자동으로 처리해준다. 

기존에는 useEffect와 useState를 조합하여 데이터를 불러와야 했지만 useQuery를 사용하면 훨씬 간결하게 데이터를 관리할 수 있다. 또한 캐싱, 자동 리페치, 서버 상태 관리 기능을 제공하여 서버 데이터 관리의 복잡성을 크게 줄여준다.

이 기능은 TanStack Query 라이브러리에서 제공된다.


2. 설치 및 기본 설정

useQuery를 사용하기 위해 먼저 TanStack Query를 설치한다.

[설치]
npm install @tanstack/react-query 

그 다음 QueryClientProvider로 앱을 감싸서 React Query를 사용할 수 있도록 설정한다.

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>
);


3. 기본 사용법

다음은 블로그 카테고리 목록을 호출하기 위한 useQuery 예시이다. 

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,
});
};

이렇게 만든 커스텀 훅을 컴포넌트에서 호출하여 데이터 상태에 따라 렌더링을 제어할 수 있다.

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>
);
}


4. useQuery 주요 옵션

useQuery에는 몇가지 주요 옵션들이 존재한다. 

- queryKey

캐싱과 리페치를 관리하는 고유 식별자이다. TanStack Query v4부터는 반드시 배열 형태로 작성해야 한다.

["categories"]
["user", userId]
["posts", { page: 1 }]

queryKey를 잘 설계하면 파라미터 기반 캐싱이 가능하다.

useQuery({
queryKey: ["user", userId],
queryFn: () => getUser(userId),
});

userId가 변경되면 자동으로 새로운 요청이 발생한다.


- queryFn

데이터를 가져오는 비동기 함수이다. 보통 API 요청 함수가 들어간다.

queryFn: () => categoryService.getCategories()


- enabled

쿼리 실행 여부를 제어하는 옵션이다. 특정 조건이 만족할 때만 요청을 보내고 싶을 때 사용한다.

useQuery({
queryKey: ["user", userId],
queryFn: () => getUser(userId),
enabled: !!userId,
});

로그인 이후 데이터를 요청해야 하거나 특정 값이 선택된 이후 API를 호출해야하는 상황 등에서 유용하다.


- staleTime

데이터가 신선한 상태(fresh)로 유지되는 시간이다. 이 시간 동안은 서버에 다시 요청하지 않고 캐시된 데이터를 사용한다.

staleTime: 1000 * 60 * 60 * 24


- gcTime

데이터가 비활성 상태(Inactive)가 된 이후 캐시가 메모리에 유지되는 시간이다. 쿼리를 사용하는 컴포넌트가 언마운트되면 타이머가 시작되며 이 시간이 지나면 캐시 데이터가 삭제된다.

gcTime은 캐시가 언제 삭제될지를 결정하는 옵션이며 staleTime과는 역할이 다르다. staleTime은 언제 다시 서버 요청을 할지와 관련된 옵션이고 gcTime은 캐시 데이터를 언제 메모리에서 삭제할지와 관련된 옵션이다.


- retry

요청 실패 시 자동으로 재시도하는 횟수이다. 기본값은 3회이다.

retry: 3


- refetchOnWindowFocus

브라우저 창이 다시 포커스 되었을 때 자동으로 데이터를 리페치할지 여부를 설정한다.

refetchOnWindowFocus: false


5. useQuery 반환 상태

useQuery는 다양한 상태 값을 제공하여 비동기 데이터를 쉽게 관리할 수 있다.

const {
data,
error,
isLoading,
isError,
isFetching,
refetch,
status
} = useQuery(...)

주요 상태 값은 다음과 같다.

  • data - 서버에서 받은 데이터
  • error - 요청 실패 시 에러 객체
  • isLoading - 최초 데이터 요청 중
  • isError - 에러 발생 여부
  • isFetching - 백그라운드에서 데이터 재요청 중
  • refetch - 수동으로 다시 요청
  • status - loading / success / error

이를 활용하여 기존 데이터를 유지하면서 백그라운드 요청 상태를 표시할 수 있다.

{isFetching && <Spinner />}


6. 데이터 가공

select 옵션을 사용하면 API 응답 데이터를 바로 가공할 수 있다.

useQuery({
queryKey: ["categories"],
queryFn: getCategories,
select: (data) => data.map((category) => category.name),
});

이렇게 하면 컴포넌트에서는 가공된 데이터만 사용할 수 있다.


7. 캐시 무효화

데이터가 변경되었을 때 캐시를 무효화하고 다시 데이터를 가져오도록 할 수 있다.

import { useQueryClient } from "@tanstack/react-query";

const queryClient = useQueryClient();

queryClient.invalidateQueries({
queryKey: ["categories"]
});

보통 데이터 생성, 수정, 삭제 이후에 사용되며 게시글 작성, 댓글 삭제, 카테고리 수정 이후 목록 데이터를 다시 불러올 때 사용한다.


8. React Query Devtools

개발 중에는 React Query Devtools를 사용하면 캐시 상태를 쉽게 확인할 수 있다.

[설치]
npm install @tanstack/react-query-devtools

import { ReactQueryDevtools } from "@tanstack/react-query-devtools";

<ReactQueryDevtools initialIsOpen={false} />

Devtools를 사용하면 쿼리 캐시 상태, 로딩 상태, 데이터 변경등을 UI에서 확인할 수 있다.

이전 글
📘 Ubuntu 서버 운영에 꼭 필요한 리눅스 기본 명령어
다음 글
🐞 검색엔진 타임아웃 문제 해결 - Sitemap 성능 최적화
장식용 로고