React Query의 Pagination과 Prefetching에 대한 기능은 앞서 공부해보았다.
이번엔 조금 더 규모가 있는 앱에서 프리패칭의 핵심 기능을 동작하는 PrefetchQuery에 대해 자사하게 알아보자.
🧐 그전에 React Query로 데이터를 미리 채우는 방법에는 무엇이 있을까?
✅ prefetchQuery
가장 핵심 기능인 prefetchQuery는 queryClient의 메서드로, 서버로 부터 받아온 데이터를 캐시에 추가한다.
✅ setQueryData
setQueryData는 queryClient의 메서드로, prefetchQuery처럼 useQuery를 실행시키지 않고 쿼리 데이터를 캐시에 추가하는 또 다른 방법이다. 단, 클라이언트에서 데이터를 받아오는데, 이 데이터는 서버에서 mutation된 상태의 데이터일 것이다.
✅ placeholderData
placeholderData는 useQuery의 옵션으로, useQuery 실행 시 데이터를 제공하기 때문에 클라이언트에서 데이터를 가져올 것이고 캐시에는 추가되지 않는다. placeholderData는 달리 표시할 데이터가 없는 경우 사용하는 임시로 채워놓는 표시용 데이터이다. (공식문서)
✅ initialData
initialData는 useQuery의 옵션으로, placeholderData와는 반대되는 개념이다. 왜냐하면 캐시에 추가해야하는 데이터가 존재한다.
✅ Prefetching의 순서
1️⃣ 사용자가 홈페이지를 load
2️⃣ 홈페이지 load시 queryClient.prefetchQuery 호출하여 데이터를 캐시에 추가
3️⃣ 사용자에게 페이지 화면을 load
4️⃣ 쿼리를 처음 prefetch한 시점을 기준으로...
cachtime 초과하지 않을 경우, 캐시에 담아둔 데이터를 load하고 더하여, useQuery에서 새로운 데이터 가져온다. 컴포넌트 마운트되어 리패칭을 트리거하여 데이터가 stale해졌다고 인식하기 때문이다. 그 동안에 캐시된 데이터가 사용자에게 보이는 것.
👉 이 것이 PrefetchQuery의 사용이유이자 진정한 기능!
cachtime 초과한 경우, 데이터는 garbage collection에 수집되고 useQuery는 그동안 표시할 수 있는 데이터 없이 데이터를 가져와야한다.
✅ Prefetch에 대한 별도 Hook 생성
// useTreatment.tsx (커스텀훅)
export const usePrefetchTreaments = (): void => {
const queryClient = useQueryClient();
queryClient.prefetchQuery(queryKeys.treatments, getTreatments);
};
//Home.tsx (실제화면에 출력될 컴포넌트)
export function Home(): ReactElement {
usePrefetchTreaments();
return ...
}
✅ useEffect를 사용하는건?
물론 화면에 출력되는 컴포넌트에 종속적으로 직접 useEffect를 사용할 수는 있다.
//Home.tsx (실제화면에 출력될 컴포넌트)
export function Home(): ReactElement {
useEffect(()=> {
queryClient.prefetchQuery(...)
},[queryClient])
return ...
}
💡 자세히 👉 prefetch with useEffect
✅ useEffect에 앞서 생성한 Hook을 넣는건?
useEffect 콜백 내에서 훅을 실행시킬 수는 없다.
//Home.tsx (실제화면에 출력될 컴포넌트)
export function Home(): ReactElement {
useEffect(()=> {
usePrefetchTreatements(); // 불가능
},[])
return ...
}
✅ 그럼 Hook이 아닌 다른 형식으로 만들면?
훅이 아닌 경우 useQueryClient를 실행시킬 수 없다.