-
Notifications
You must be signed in to change notification settings - Fork 3
prefetchQuery 와 suspense
Tanstack Query 에는 비동기 데이터를 캐싱하고, 관리하는 많은 도구가 있다.
그중 prefetchQuery
와 ensureQueryData
를 적절히 선택해 사용해보려고 한다.
- 쿼리가 필요해지거나, useQuery 친구들이 포함된 컴포넌트가 렌더링되기 전에 미리 데이터를 가져오는 비동기 메서드이다.
- 데이터를 불러와 캐싱하고, queryKey 가 동일한 쿼리가 실행되면 이 캐싱된 데이터를 사용하게 된다.
-
Promise<void>
, 즉, 반환값이 없다.
- 캐시된 데이터가 있으면 반환하고, 없으면 데이터를 가져오는 비동기 메서드이다.
- 반환값이 있다.
현재 라우트는 다음과 같이 구성되어 있다.
export const Route = createFileRoute('/_auth/$project/board')({
...
loader: ({ context: { queryClient }, params: { project } }) => {
const projectId = Number(project);
// prefetchQuery or ensureQueryData ?
return { projectId };
},
component: () => (
<Suspense fallback={<LoadingFallback />}>
<Board />
</Suspense>
),
});
칸반보드를 그려내기 위해 최초 1회 전체 태스크 목록을 불러오는데, (그 후에는 5분 간격으로 갱신). 어떤 것이 더 알맞는 사용방식일까?
우선, 데이터를 가져오는 방식을 확인해본다.
실제 이 라우트의 loader
에서 해당 데이터를 사용할 필요가 있는가? 아니다..
데이터는 <Board>
컴포넌트 내부의 useSuspenseQuery
에서 사용할 것이다.
그 다음은 캐싱 여부이다.
ensureQueryData
는 기존의 캐싱된 데이터가 있다면, 이를 활용한다.
하지만, 사용자가 이 보드 페이지에 접근을 시도하면, 기존에 캐시 되어있던 데이터가 아닌 최신 데이터를 불러와야 한다. 따라서, prefetchQuery
가 적합해 보인다.
prefetchQuery
는 사용자가 페이지를 이동하기 전에 데이터를 미리 캐싱해준다.
graph TD
A[라우트 전환 시작] --> B[loader 실행]
B --> C[prefetchQuery 실행]
C --> D[캐시에 데이터 저장]
D --> E[Board 컴포넌트 마운트]
E --> F[useSuspenseQuery 실행]
F --> G[캐시된 데이터 즉시 사용]
그렇다면 Suspense
왜 필요한걸까?
prefetchQuery
가 미리 데이터를 캐싱하려 시도하긴 하지만,
네트워크가 불안정하거나, prefetchQuery
가 느리게 동작한다면, 컴포넌트는 이미 렌더링이 시작되었을 수 있다.
즉, 데이터 캐싱이 완료되기 전에 컴포넌트가 마운트되는 것을 방지하기 위함이다.
캐싱이 끝나기전에 <Board>
컴포넌트가 마운트를 시도하면, Suspense 가 이 컴포넌트의 렌더링을 막고 기다리는 것이다.
따라서, prefetchQuery
가 느리게 동작할 때에도, 더 나은 사용자 경험을 제공할 수 있게 된다.
아래 블로그에 잘 정리되어 있어서 많이 배웠습니다.
- 1. 1주차 팀 빌딩 및 기획 회의
- 2. 1주차 두 번째 기획 회의
- 3. 1주차 세 번째 기획 회의
- 4. 1주차 기획 공유 발표 전 회의
- 5. 2주차 라이브러리, 개발 환경 관련 회의
- 6. 2주차 모노레포 관련 회의
- 7. 2주차 실시간 통신 기술 회의
- 8. 2주차 실시간 목표치, 발표 준비 회의
- 9. 3주차 주간 계획 회의
- 10. 4주차 주간 계획 회의
- 11. 4주차 팀 목표 재설정 회의
- 12. 4주차 기능 추가 회의
- 13. 4주차 플래닝 포커 회의
- 14. 5주차 주간 계획 회의
- 15. 5주차 이미지 업로드 관련 회의
- 16. 5주차 칸반 보드 회의
- 17. 5주차 데모 및 최종 발표 회의
🧾 회고 캘린더