시작하며...
내 블로그에 [React] 리액트 쿼리(React-Query) 사용 방법 이런 게시물이 있다.
그리고 당시 했던 프로젝트를 보니깐 React Query 의 버전이 3이었다.
그러나 현재 V5 까지 있으며, React 이 외에도 Vue 등에서도 사용이 가능해지면서 TanStack Query 로 이름을 바꿨다고 한다. 그래서 더 자세히 공부할 겸 새로운 내용들을 알기 위해 글을 작성하기로 했다.
TanStack Query V5
정의
TanStack Query 란 무엇일까?
TanStack Query
it makes fetching, caching, synchronizing and updating server state in your web applications a breeze.
웹 애플리케이션에서 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 보다 쉽게 다룰 수 있도록 도와줌.
[출처] TanStack Query 공식문서
즉, 서버로 부터 데이터를 받을 때 서버의 상태를 관리하기 위해 만들어진 라이브러리이다.
기능
- 캐싱
- 동일한 데이터에 대한 중복 요청을 단일 요청으로 통합
- 백그라운드에서 오래된 데이터 업데이트
- 데이터가 얼마나 오래되었는지 알 수 있다.
- 데이터 업데이트를 가능한 빠르게 반영
- 페이지네이션 및 데이터 지연 로드와 같은 성능 최적화
- 서버 상태의 메모리 및 가비지 수집 관리
- 구조 공유를 사용하여 쿼리 결과를 메모화
TanStack Query 세팅하기
설치
터미널창에 명령어를 입력하여 TanStack Query(React) 를 설치한다.
npm i @tanstack/react-query
QueryClient
TanStack Query 의 기능을 사용하기 위해 QueryClient
의 인스턴스를 생성하고 QueryClientProvider
를 최상단에서 감싸주고 QueryClient
인스턴스를 client props로 넣어 애플리케이션에 연결한다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}>
<React.StrictMode>
<App />
</React.StrictMode>
</QueryClientProvider>
);
Query Client
에 추가적인 옵션을 넣을 수 있는데 이에 대한 자세한 내용은 여기서 확인할 수 있다.
Devtools
Devtools
는 사용하면 TanStack Query 의 모든 내부 동작을 시각화하는 데 도움을 주며 문제가 발생하면 디버깅 시간을 절약할 수 있다.
이는 process.env.NODE_ENV === 'development'
인 경우에만 실행된다. 즉, 개발 환경에만 실행되기때문에 배포하기 위해 해당 코드를 삭제할 필요가 없다.
세팅하기
먼저 터미널창에 명령어를 입력하여 Devtools
를 설치하고
npm i @tanstack/react-query-devtools
ReactQueryDevtools
컴포넌트를 내 어플리케이션 하단에 배치해준다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}>
<React.StrictMode>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</React.StrictMode>
</QueryClientProvider>
);
그러면 프로젝트 하단에 Devtools
가 생기며 여기서 모든 내부 동작을 시각화 할 수 있다.
TanStack Query 사용하기
useQuery
Tanstack Query 에는 다양한 API refernce가 존재하는데 그 중 서버의 GET 요청
에 대한 데이터를 관리해주기 위해 useQuery
를 사용한다.
useQuery
는 v5 부터 인자로 단 하나의 객체만 받는다. 그 중에 queryKey
, queryFn
는 필수 값이다.
기본 사용법
useQuery
를 import 하고
import { useQuery } from '@tanstack/react-query';
queryKey
에는 데이터를 고유하게 식별하는 key 이며, queryFn
에는 호출하고자 하는 함수를 넣어준다.
function App() {
const getTestData = async () => {
const { data } = await axios.get(
'https://jsonplaceholder.typicode.com/posts/1'
);
return data;
};
const { data, isLoading, isError } = useQuery({
queryKey: ['test'],
queryFn: getTestData,
});
// 로딩중
if (isLoading) {
return <div>Loading...</div>;
}
// 에러
if (isError) {
return <div>Error fetching data</div>;
}
// 데이터 가져옴
if (data) {
return <div>{data.title}</div>;
}
}
그러면 정상적으로 데이터를 가져왔을 때 화면에 title 이 출력되었고 Devtools
를 통해 받은 data 를 상세하게 볼 수 있다.
또한 Trigger Loading, Trigger Error 버튼을 통해 해당 경우가 발생했을 때 결과도 볼 수 있다.
(Trigger Error 버튼 누른 경우)
queryOptions
queryOptions
를 사용해 공통된 옵션을 설정할 수 있다. 그리고 매개변수화 하여 post 의 번호에 따라 동적으로 데이터를 가져올 수 있다.
import { useQuery, queryOptions } from '@tanstack/react-query';
import axios from 'axios';
function App() {
...
const testOption = {
test: (testId: number) =>
queryOptions({
queryKey: ['test', testId],
queryFn: () => getTestData(testId),
}),
};
const { data: data1 } = useQuery({
...testOption.test(1),
});
const { data: data2 } = useQuery({
...testOption.test(2),
});
...
}
useQueries
위에 코드처럼 이렇게 작성하면 쿼리 함수들이 그냥 병렬로 요청된다.
const { data: data1 } = useQuery({
...testOption.test(1),
});
const { data: data2 } = useQuery({
...testOption.test(2),
});
하지만 동시에 쿼리 함수들을 요청하고 싶을 때, useQueries
를 사용할 수 있다.
const queryResult = useQueries({
queries: [{ ...testOption.test(1) }, { ...testOption.test(2) }],
});
return (
<div>
<h1>{queryResult[0].data?.title}</h1>
<p>{queryResult[1].data?.body}</p>
</div>
);
그러면 동시에 쿼리 요청을 하고 코드의 길이도 줄일 수 있게 된다.
그 외
그 외 useQuery
에 대한 option 들과 return data 들은 공식문서 에서 자세하게 확인할 수 있다.
만약 사용자가 자주 사용하지 않는 데이터이면서 메모리를 낭비하고 싶지 않을 때, option 속성에 gcTime
을 길게 설정하여 해당 시간 동안 쿼리 인스턴스가 새롭게 mount 되어도 네트워크 요청(fetch)이 일어나지 않게 할 수 있다.
이러한 내용들이 공식문서 에 있으니 한 번 쯤 읽어보는 것을 추천한다.
useMutation
useQuery
는 서버에서 데이터를 GET 할 때 사용되고, 그 이 외의 POST, PATCH, PUT, DELETE 인 경우는 useMutation
을 사용한다.
기본 사용법
useMutation
을 import 한다.
import { useMutation } from '@tanstack/react-query';
호출을 하기위해 반환된 mutation
객체의 mutate
메서드를 이용하여 함수를 호출한다.
<button onClick={() => mutation.mutate()}>버튼</button>
onMutate
는 mutation 함수가 실행되기 전에 실행되고, onSettled
는 try-catch-finally 의 finally 처럼 요청이 성공하든 에러가 발생되든 상관없이 마지막에 실행된다.
const postWriteData = async () => {
// 생략
};
const mutation = useMutation({
mutationFn: postWriteData,
onMutate() {
console.log('mutation 실행 전');
},
onSuccess(data) {
console.log(data);
},
onError(err) {
console.error(err);
},
onSettled() {
console.log('finally 처럼 마지막에 실행');
},
});
그러면 console.log 이 찍히는 것과 Devtools
를 통해 보낸 data 를 상세하게 볼 수 있다.
마무리 하며...
이 글에 담지는 못했지만 지난 번과 다르게 이번에는 공식 문서를 보면서 전에 알지 못했던 다양한 기능들도 찾아보았다. 정말 다양한 기능을 제공하며 TanStack Query 의 기능을 최대한 이용하면서 효율적인 코드를 작성해보고 싶다고 생각하게 되었다.
[참고] TanStack Query(aka. react query) 에서 자주 사용되는 개념 정리
'💜 리액트 > 라이브러리' 카테고리의 다른 글
[React] Zustand 상태 관리 라이브러리 사용 방법 (0) | 2024.03.03 |
---|---|
[React] TanStack Query 에서 Suspense 사용 (+ ErrorBoundary) (2) | 2024.03.01 |
[React] Firebase 로그인 - Authentication (1) | 2024.01.03 |
[React] Firebase 회원가입 - Authentication (0) | 2024.01.02 |
[React] React-Hook-Form 회원가입 입력 폼 유효성 검사 (1) | 2023.12.31 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!