한 줄 정의
usePrefetchQuery는 렌더 도중에 쿼리를 미리 받아 두게 하는 훅이다. 아무것도 반환하지 않고, 데이터를 구독하지도 않는다.
아래쪽 컴포넌트가 useSuspenseQuery로 그 데이터를 쓰기 전에, 부모에서 미리 불러오기를 걸어 두는 용도다.
작동 원리
이 훅은 렌더 시점에 prefetch를 한 번 쏜다. 그게 전부다. 반환값이 없고, 요청이 끝나도 컴포넌트를 다시 그리지 않는다. 즉 데이터를 이 훅으로 읽는 게 아니라 캐시에 미리 채워 두기만 한다. 공식 문서도 "usePrefetchQuery는 아무것도 반환하지 않으며, 렌더 도중 prefetch를 쏘는 용도로만 쓴다"고 못 박는다.
핵심은 위치다. useSuspenseQuery를 쓰는 컴포넌트를 감싼 Suspense 경계 앞에서 불러야, 그 경계가 멈춰 있는 동안 데이터가 병렬로 채워진다.
쓰는 법
옵션은 queryClient.prefetchQuery와 같다. queryKey는 필수, queryFn은 기본 쿼리 함수가 없으면 필수다.
import { Suspense } from 'react'
import { usePrefetchQuery } from '@tanstack/react-query'
import { Article } from './Article'
export function ArticlePage({ id }: { id: string }) {
// Article이 쓸 데이터를 미리 건다
usePrefetchQuery({
queryKey: ['article', id],
queryFn: () => fetchArticle(id),
})
return (
<Suspense fallback={<p>불러오는 중…</p>}>
<Article id={id} />
</Suspense>
)
}
실전 예제
Suspense로 나눈 화면에서 렌더 워터폴을 줄일 때 쓴다. Article이 렌더되며 useSuspenseQuery를 부르기 시작하면 그때부터 요청이 나가지만, 부모에서 usePrefetchQuery로 미리 걸어 두면 Suspense가 멈춘 시점에 이미 요청이 진행 중이다. 렌더가 데이터를 기다리는 시간이 줄어든다.
쓰는 이유
usePrefetchQuery는 없어도 앱이 돌아간다. 같은 일을 서버 쪽 prefetch나 라우터 로더로도 할 수 있다. 이 훅의 값은 Suspense 컴포넌트 트리에서 렌더 워터폴을 줄이는 좁은 지점에 있다. Suspense를 적극적으로 쓰고 요청 순서를 다듬는 단계에서 꺼내는 도구라, 처음부터 손이 가는 훅은 아니다.
Reference