개인 프로젝트이던 팀 프로젝트이던 사용하는 데이터 통신들이 복잡해질수록 react-query의 필요성을 크게 느끼고 적용해왔다. 하지만 공식문서를 정독하거나, 효율적으로 사용을 한 건 아닌 것 같다. 따라서 다시 제대로 공부하고 정리하는 시간을 가지며 프로젝트에 더 좋은 코드를 적용하고 싶다. 🥺
강력한 비동기 상태 관리 라이브러리
Tanstack Query는 개발자에게 보다 간편하고 효율적으로 data fetching을 할 수 있도록 해준다.
데이터를 어디서 가져올 지와 필요한 신선도(데이터의 fresh한 상태를 얼마나 유지할 지)를 알려주면 나머지는 자동으로 처리한다. 캐싱, 백그라운드 업데이트, 오래된 데이터 처리 등도 자동으로 처리해준다.
또 Promise나 async/await을 안다면 바로 사용할 수 있다. 전역 상태를 관리하거나 리듀서, 정규화 시스템 또는 복잡한 구성을 이해할 필요가 없이, 함수를 전달하면(또는 오류를 던져주면), 나머지는 😉
그리고 각 쿼리의 옵저버 인스턴스에 대해 맞춤형 설정과 옵션으로 구성할 수 있다. Devtools, Infinite-loading API 및 데이터 업데이트를 위한 일급 Mutation tools이 제공되어 작업자의 편의를 높여준다.
react-query 설치 (devtool은 선택)
$ npm i @tanstack/react-query @tanstack/react-query-devtools
# or
$ yarn add @tanstack/react-query @tanstack/react-query-devtools
const queryClient = new QueryClient()
: 쿼리 클라이언트를 생성한다.
<QueryClientProvider client={queryClient}>
: 프로바이더로 쿼리를 사용할 앱에 씌워준다.
<ReactQueryDevtools initialIsOpen={false} />
: Devtools 사용 시 추가한다.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
// 1. Create a client
const queryClient = new QueryClient();
function App() {
return (
// 2. Provide the client to your App
<QueryClientProvider client={queryClient}>
// 3. Devtools 사용 시
<ReactQueryDevtools initialIsOpen={false} />
<Home />
</QueryClientProvider>
);
}
export default App;
useQuery({ queryKey: ['고유 키'], queryFn: fetch 함수(비동기),옵션})
useQuery
템플릿 및 기타 데이터 사용에 필요한 쿼리에 대한 모든 정보가 들어있다.import { useQuery } from '@tanstack/react-query'
export default function MusicList() {
const query = useQuery({
queryKey: ['musics'],
queryFn: async () => {
const res = await fetch(`data/musics.json`);
return res.json();
},
});
console.log(query);
...
이제 데이터를 사용해서 화면에 나타내보자.
import { useQuery } from '@tanstack/react-query';
export default function MusicList() {
const { data: musics } = useQuery<Music[]>({
queryKey: ['musics'],
queryFn: async () => {
const res = await fetch(`data/musics.json`);
return res.json();
},
});
...
{ data: '받아올이름'}
: data를 musics이라는 이름으로 가져왔다. (data로만 사용해도 된다.)queryKey: ['musics', checked ]
import { useQuery } from '@tanstack/react-query';
type Music = { title: string; singer: string; id: string };
export default function MusicList() {
const [checked, setChecked] = useState(false);
const { isLoading, isError, data: musics } = useQuery<Music[]>({
queryKey: ['musics', checked],
queryFn: async () => {
const res = await fetch(`data/${checked ? 'new_' : ''}musics.json`);
console.log('💡데이터 받아옴');
// 일부러 error를 던져줌!
throw new Error('error');
},
});
if (isLoading) return <p>Loading...</p>;
if (isError) return <span>Error</span>;
...
공식 문서에 따르면
useQuery
나 useInfiniteQuery
로 만들어진 쿼리 인스턴스는 기본적으로 캐시된 데이터를 stale(오래된) 한 것으로 간주한다.
따라서 이를 바꾸려면 staleTime
옵션을 사용해야한다.
🔆 stale queries는 자동적으로 백그라운드에서 refetch한다.
When :
- 새로운 쿼리가 마운트되었을 때 == 컴포넌트가 다시 쿼리를 이용했을 때
- 윈도우가 다시 자동으로 포커스되었을 때
- 네트워크가 다시 연결되었을 때
- 쿼리가 refetch interval이 설정이 되었을 때 (몇초간격으로 리페치할 건지)
const {
...
} = useQuery<Music[]>({...,
staleTime: 5000, //5초
});
staleTime
은 네트워크 요청의 성격에 따라 세심하게 생각하고 설정하자.
예를 들어 쇼핑몰의 물건 데이터들은 좀 길게 해도 될 것이다. 바로바로 물건들이 업데이트 되거나 하지 않기 때문에!
데이터가 추가되면 지금 화면에서는 어떻게 나타날까?
const queryClient = useQueryClient()
...
queryClient.invalidateQueries({ queryKey: ['musics'] })
이상으로 tanstack query 로 간단한 예제를 구현해보며 기본적인 사용법을 익혀보았다. 다음 포스팅에서는 데이터를 생성/업데이트/삭제하거나 서버 부작용을 수행하는 데 사용되는 Mutation에 대해서 자세히 다뤄볼 예정이다.
감사합니다. 다음 글이 기다려지네요.