안녕하세요~ 오늘은 약간 가벼운 주제로 가져오게된 react-query의 fetchQuery
와 prefetchQuery
에 대한 내용입니다.
보통 Next.js를 이용하여 ssr을 이용하실때 그냥 fetch만으로 이용하시는 경우도 있지만 경우에 따라서 react-query
를 사용할 때가 있습니다.
그런 경우 react-query에서는 prefetchQuery
라는 메서드를 이용하여 ssr을 사용할 수 있도록 제공합니다.
const queryClient = getQueryClient();
await queryClient.prefetchQuery({
queryKey: ['test'],
queryFn: getTest
});
다음과 같이 prefetchQuery를 Next.js 12
에서는 getServerSideProps
, getStaticSideProps
, Next.js 13 (App router)
에서는 server component에서 이용하시면 server에서 미리 데이터를 만들어 놓은 후 이 다음에 fetch하는것에는 이미 완성된 초기 데이터를 이용하는것이죠.
const {data} = useQuery(['test'], getTest);
...
실제 사용할때는 client단에서 prefetchQuery
를 이용했던것과 동일한 query key를 설정하시면 됩니다.
이렇게 이용할시 기존에 data가 undefined (pending) -> data (fulfilled) 되던 방식이 undefined가 initial data로 초기화 되있는 상태가 됩니다.
이제는 fetchQuery에 대해서 얘기해봐야겠죠?
사실 대부분 react-query에서 ssr을 이용할때 prefetchQuery
를 이용합니다.
https://tanstack.com/query/v4/docs/react/guides/ssr
docs만 봐도 prefetchQuery로 하는 예시로만 되어있어 보통 이것만 이용하는 경우가 많습니다.
하지만 prefetchQuery는 항상 성공한 쿼리만 dehydrate
를 해주게 됩니다. 그리고 성공한 데이터에 대해서 결과값을 return을 하지 않습니다.
반면에 fetchQuery
는 실패할 경우 에러를 던지며, 결과값에 대한 return을 할 수 있습니다.
보통 저는 2가지 케이스에서 이용을 합니다.
hydrateAtom
초기화⭐️ server에서 받은 queryData를 통하여 jotai의 hydrateAtom
초기화
const SearchFilter = () => {
const queryClient = getQueryClient();
const searchFilter = await queryClient.fetchQuery({
queryKey: ['searchFilter', DEFAULT_SEARCH_FILTER],
queryFn: () => getSearchFilter(params),
});
return (
<HydateAtomProvider atomKey="searchFilterInputAtom" value={searchFilter}>
<SearchFilterContents data={searchFilter} atomValue={atomValue} />
</HydateAtomProvider>
);
}
⭐️ ssr에서의 error boundary를 이용할시
// HydratedList.tsx
export const HydratedList = async ({ params }: Params) => {
const queryClient = getQueryClient();
await queryClient.fetchInfiniteQuery({
queryKey: ['searchResult'],
queryFn: () => getList(params),
});
const dehydratedSearchResult = dehydrate(queryClient);
return (
<Hydrate state={dehydratedSearchResult}>
<List params={params} />
</Hydrate>
);
};
// page.tsx
<ErrorBoundary FallbackComponent={NoSearchContents}>
<HydratedCarList params={params} />
</ErrorBoundary>
여기서도 보셨듯이 fetchInfiniteQuery를 사용하시면 무한스크롤이나 페이지네이션에 이용하는 useInfiniteQuery에 대해서 ssr처리를 할 수 있습니다. (prefetchInfiniteQuery도 있습니다.)
이제는 기능구현 글은 안쓰시나요 ㅜ