TanStack Query (React Query)
웹 애플리케이션에서 서버 상태를 가져오고, 캐싱하고, 동기화하고, 업데이트하는 작업을 아주 쉽게 해주는 API.
기존에는 해당하는 데이터의 로딩, 에러, 캐싱, 갱신을 직접 관리했어야 했지만, React Query가 알아서 해준다.
- 서버로부터 데이터를 가져오는 건 useQuery
- 데이터 생성, 수정, 삭제 같은 작업은 useMutation
- 쿼리의 결과를 자동으로 캐싱, 관리
- QueryClientProvider를 앱 루트에 적용해줘야 캐싱 가능
설치
npm i @tanstack/react-query
queryClientprovider을 붙여주어야지 캐싱 가능
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourComponents />
</QueryClientProvider>
);
}
서버에서 데이터 가져오기 — useQuery
const { isPending, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
});
상태값
isPending 또는 status === 'pending' | 쿼리 실행 중 |
isError 또는 status === 'error' | 에러 발생 |
isSuccess 또는 status === 'success' | 데이터 성공 반환 |
queryKey
데이터를 식별하고 관리하는 고유 값
- 첫 번째 요소: 요청 자원명 (리소스 식별자)
- 두 번째 이후: 쿼리를 다시 수행시킬 기준 (해당 값이 변하면 쿼리 다시 실행)
queryKey: ['user', userId]
=> 변할 가능성이 있는 값은 반드시 key에 넣어주어야 한다
useQuery 옵션
queryKey | 고유 쿼리 식별자 (배열 형태) |
queryFn | 데이터를 fetch하는 비동기 함수 |
enabled | 자동 실행 여부 (false 시 수동 호출 가능) |
select | 데이터를 가공해서 반환 |
staleTime | 데이터가 오래됐다고 간주하기 전까지의 시간 (ms) |
cacheTime | 메모리에 캐시를 유지하는 시간 (ms) |
refetchOnWindowFocus | 윈도우 포커스 시 다시 호출 여부 (true, false, 'always') |
retry | 실패 시 재시도 횟수/여부 |
onSuccess | 성공 시 실행할 콜백 |
onError | 실패 시 실행할 콜백 |
useMutation _ 데이터 생성/수정/삭제
const mutation = useMutation({
mutationFn: (newTodo) => axios.post('/todos', newTodo),
onSuccess: () => {
// 성공했을 때 처리
},
onError: (error) => {
// 실패했을 때 처리
},
onSettled: () => {
// 성공이든 실패든 처리
},
});
서버 상태를 변경하는 요청은 무조건 useMutation
=> 성공 시 해당하는 쿼리 캐싱을 무효화(invalidateQueries)해서 화면을 최신 상태로 유지 가능
useMutation 정리
mutationFn | 서버 요청 함수 |
onSuccess | 성공 시 콜백 |
onError | 실패 시 콜백 |
onSettled | 성공/실패 상관없이 실행 |
삭제용 Mutation 예제
"use client";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { removeBook } from "@/service/books"; // 삭제 요청 API 함수
import { useRouter } from "next/navigation";
// queryClient 가져오기 (invalidateQueries 호출용)
const queryClient = useQueryClient();
const router = useRouter();
// 삭제 Mutation 선언
const removeMutation = useMutation({
// 삭제 요청 함수 — isbn 값을 받아서 API 호출
mutationFn: (isbn: string) => removeBook(isbn),
// 성공 시 실행되는 콜백
onSuccess: () => {
alert("삭제 성공");
// 캐싱된 'books' 목록 데이터 무효화 → 목록 새로고침되게
queryClient.invalidateQueries(["books"]);
// 삭제 후 목록 페이지로 이동
router.push("/books");
},
// 실패 시 실행되는 콜백
onError: () => {
alert("삭제 실패");
},
});
// 삭제 버튼 클릭 시 실행 함수
const handleRemove = (isbn: string) => {
if (confirm("정말 삭제하시겠습니까?")) {
// 삭제 mutation 호출
removeMutation.mutate(isbn);
}
};
'React' 카테고리의 다른 글
React Context API와 LocalStorage로 상태 관리 (0) | 2025.04.23 |
---|---|
Context 알아보기 (0) | 2025.04.22 |
Axios와 async/await (2) | 2025.04.16 |
React & Next.js 활용해보기 / CSR vs SSR (1) | 2025.04.14 |
React TypeScript 활용해보기 (1) | 2025.04.11 |