@tanstack/react-query 살펴보기
KUKJIN LEE • 2주 전 작성
@tanstack/react-query
는 서버 상태 관리 라이브러리로, Next.js와 같은 React 기반 애플리케이션에서 서버 데이터의 fetching, caching, synchronizing, 업데이트를 효율적으로 관리하는 데 사용됩니다. 이를 통해 서버에서 데이터를 불러오고 캐싱하여 상태를 손쉽게 관리할 수 있습니다.
React Query는 서버 데이터의 로딩, 오류 처리, 리프레시, 중복 요청 방지 등을 포함한 복잡한 로직을 간소화해주며, 개발자가 상태 관리보다는 비즈니스 로직에 집중할 수 있도록 돕습니다.
설치 방법
npm install @tanstack/react-query
기본 사용 방법
React Query를 사용하기 위해서는 QueryClient
와 QueryClientProvider
를 설정해야 합니다. 이를 통해 React 컴포넌트에서 데이터를 가져오고 관리할 수 있는 환경을 제공합니다.
QueryClient 설정하기
QueryClient
는 React Query의 중심 객체로, 모든 쿼리와 캐시 상태를 관리합니다. 아래는 Next.js나 일반 React 애플리케이션에서 기본 설정을 하는 방법입니다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// QueryClient 생성
const queryClient = new QueryClient();
// React 애플리케이션에 QueryClientProvider 설정
ReactDOM.createRoot(document.getElementById('root')).render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);
기본 쿼리 사용하기
React Query를 사용하여 데이터를 가져오는 가장 간단한 방법은 useQuery
훅을 사용하는 것입니다. useQuery
는 데이터를 가져오기 위한 쿼리를 생성하며, 로딩 상태와 오류 처리도 자동으로 관리해 줍니다.
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
function Todos() {
// "todos" 쿼리 키로 데이터 가져오기
const { data, isLoading, error } = useQuery(['todos'], async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/todos');
return response.data;
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
쿼리 키의 중요성
useQuery
는 쿼리 키를 통해 데이터를 식별합니다. 쿼리 키는 캐싱과 리페칭을 결정하는 중요한 요소로, 동일한 키를 사용하면 React Query는 캐시된 데이터를 재사용하거나 필요에 따라 업데이트합니다.
데이터 업데이트: useMutation 사용하기
서버 데이터를 변경할 때는 useMutation
훅을 사용할 수 있습니다. 예를 들어, 새 항목을 추가하거나 기존 항목을 삭제하는 등의 작업을 수행할 수 있습니다.
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';
function AddTodo() {
const queryClient = useQueryClient();
const mutation = useMutation(
newTodo => axios.post('https://jsonplaceholder.typicode.com/todos', newTodo),
{
onSuccess: () => {
// 데이터를 성공적으로 업데이트한 후 "todos" 쿼리를 무효화하여 새 데이터를 가져옴
queryClient.invalidateQueries(['todos']);
},
onError: (error) => {
// 데이터 업데이트 중 오류가 발생한 경우 처리
console.error('Error adding todo:', error);
},
onSettled: () => {
// 성공 또는 실패 후 항상 실행되는 콜백
console.log('Mutation has been settled.');
},
}
);
const handleAddTodo = () => {
mutation.mutate({ title: '새 할 일', completed: false });
};
return (
<button onClick={handleAddTodo} disabled={mutation.isLoading}>
{mutation.isLoading ? '추가 중...' : '할 일 추가'}
</button>
);
}
캐싱 및 리패칭
React Query는 데이터 캐싱과 리패칭 기능을 제공합니다. 기본적으로, 동일한 쿼리 키로 요청 시 캐시된 데이터가 있는 경우 이를 사용하고, 정해진 시간이 지나거나 설정에 따라 새 데이터를 자동으로 가져옵니다. 이러한 기능을 통해 API 호출을 줄이고, 사용자 경험을 향상시킬 수 있습니다.
캐싱과 관련된 몇 가지 옵션은 다음과 같습니다:
-
staleTime
: 데이터가 신선한 상태로 유지되는 시간 (기본값은 0초). -
cacheTime
: 캐시된 데이터를 메모리에 유지하는 시간. -
refetchOnWindowFocus
: 사용자가 창을 다시 포커싱할 때 데이터를 리패칭할지 여부.