말 그대로 Data들을 미리 가져오는 것을 의미한다.
만약 HAO SHOP를 방문하는 사용자들이 꼭 Lookbooks를 페이지를 들어가 직원들의 룩북을 본다고 가정해보자.
export const Layout = () => {
return (
<>
<Header />
<Suspense fallback={<p>Loading...</p>}>
<Outlet />
</Suspense>
</>
);
};
데이터를 가져오기까지 Suspense를 통해 로딩창을 보여주고, 데이터를 응답받은 다음에 룩북 페이지에 렌더링되는 것을 확인할 수 있다. 하지만 이런 부분들을 prefetch를 통해 좀 더 나은 사용자 경험을 제공할 수 있다.
export const Prefetch = () => {
const queryClient = useQueryClient();
useEffect(() => {
queryClient.prefetchInfiniteQuery({
queryKey: [queryKeys.lookbooks],
queryFn: ({ pageParam = 1 }) => getLookbooks(pageParam),
});
}, [queryClient]);
return <Outlet />;
};
HomePage에서 prefetch를 하지 않은 이유는 사용자가 꼭 HomePage를 통해 들어온다는 보장도 없고, 어떠한 페이지에 들어와도 이후 Lookbooks를 들어간다고 가정하여 다음과 같은 Prefetch 컴포넌트를 작성했다.
<Route element={<Prefetch />}>
<Route element={<Layout />}>
<Route element={<PersistLogin />}>
<Route index element={<Home />} />
<Route path='lookbooks'>
<Route index element={<Lookbooks />} />
<Route path=':lookbookId' element={<Lookbook />} />
</Route>
<Route path='signup' element={<Signup />} />
<Route path='signin' element={<Signin />} />
</Route>
</Route>
</Route>
위 코드처럼 Router 파일에 Prefetch 컴포넌트를 감싸면 사용자가 HAO SHOP을 방문했을 때 Prefetch 컴포넌트를 거치게 되고, lookbooks 데이터를 prefetch할 수 있도록 선언적으로 코드를 작성했다.
어떠한 페이지를 통해 들어와도 Lookbooks 페이지로 이동하면 cacheTime 이내에 Suspense를 거치지 않고 바로 stale한 데이터를 보여줌으로써 좀 더 나은 사용자 경험을 제공할 수 있다.
당연히 쇼핑몰인만큼 상품 데이터에 대해서도 prefetch를 할 예정이다.