React Query에 대해 간단히 정리.
React Query는 서버와의 통신 작업을 진행할 때 반복적으로 발생하는 번거로운 작업을 안정적으로 대신해주는 역할을 한다고 이해하고 있다. 데이터의 상태와 생명 주기를 관리해주는 도구로 볼 수 있고, 사용했을 때 코드가 간결해지고 유지 보수가 쉬워지는 장점이 보인다.
React Query는 고맙게도 데이터를 가져온 뒤 그 결과를 상태로 관리해준다. useState와 useEffect를 이용해 직접 데이터를 다루지 않아도 되고, 로딩 중이나 에러가 발생하는 상황의 처리도 더 간결한 방식으로 사용할 수 있다.
const { data, isLoading, isError } = useQuery(['api이름'], 초기로드함수);
- data: 데이터를 성공적으로 가져온 경우 여기에 데이터가 담긴다.
- isLoading: 데이터가 로딩 중일 때
- isError: 데이터 로드 실패 시
React Query는 데이터 요청을 캐싱한다. 무슨 얘기냐면 데이터 변경 없이 컴포넌트가 다시 렌더링 되어야 하는 상황에서 동일한 데이터에 대한 불필요한 추가 요청을 막아준다. 이전 데이터를 캐시에서 가져오는데, 사용자가 원하면 invalidateQueries
를 통해 캐시를 무효화하고 최신 데이터를 가져오도록 할 수도 있다.
구현 패턴은 비슷해지는데
1. useQuery로 데이터를 가져오고
2. useMutation을 사용해 데이터를 수정한다. 그리고 queryClient.invalidateQueries로 데이터를 갱신한다.
// api 호출부.
import axios from 'axios';
export const fetchItems = async () => {
const response = await axios.get('/items');
return response.data;
};
export const updateItem = async ({ id, field1, field2 }) => {
const response = await axios.put(`/items/${id}`, { field1, field2, });
return response.data;
};
// 컴포넌트에서 사용
import React from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { fetchItems, updateItem } from './api';
const 컴포넌트 = () => {
const queryClient = useQueryClient();
const { data: items, isLoading, isError, refetch } = useQuery(['items'], fetchItems);
// 업데이트 시 mutation.mutate() 식으로 사용.
const mutation = useMutation(updateItem, {
onSuccess: () => {
queryClient.invalidateQueries(['items']); // 서버 데이터와 다시 동기화
},
});
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error loading data</div>;
// 렌더링 코드 반환 구문
};