개발자
류준열

prefetchQuery 이용해서 로딩제거

테이블 컴포넌트의 로딩에 대해 고민하다가 한 작업이다.

Table 데이터를 첫 렌더링때는 서버컴포넌트에서 받은 데이터를 보여주고, 그 이후 인터렉션이 발생하면 클라이언트에서 fetch를 할 수 있지 않을까? 라는 생각을 했다.

두가지가 맘에 걸렸다.

  • 페이지를 넘겼을때 서버 컴포넌트에서 받아온 데이터를 어떻게 클라이언트 사이드 데이터로 교체 할 것인가
  • next 서버에서 데이터를 받아올때 revalidateTime은 어떻게 설정해야 하는가

고민하던 중 tanstack query의 advanced serverside rendering을 보고 해답을 찾았다.

서버 컴포넌트에서 prefetchQuery를 사용해 데이터를 미리 캐싱한 후, HydrationBoundary를 활용해 클라이언트에서 즉시 데이터를 사용할 수 있도록 했다.

서버 컴포넌트에서 데이터 캐싱하기

import { dehydrate, QueryClient } from '@tanstack/react-query';
import { getDevices } from '@/api/devices';

export default async function Page() {
  const queryClient = getQueryClient();
 
  // ['devices',1,'']에 getDevices의 데이터가 캐싱된다.
  await queryClient.prefetchQuery({
    queryKey: ['devices',1,''],
    queryFn: getDevices,
  });

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
		  {children}
		</HydrationBoundary>
  );
}

이렇게 서버컴포넌트에서 prefetchQuery를 하게 되면 ['devices',1,''] 에 대한 결과를 렌더링전에 미리 캐싱하므로, 클라이언트에서 동일한 쿼리키 ['devices',1,''] 를 가진 api의 응답값은 캐시에서 가져온다(=로딩을 제거 할 수 있다.)