무엇
usePrefetchInfiniteQuery는 렌더 도중 무한 쿼리를 미리 가져오는 훅이다. Suspense로 감싼 자식이 useSuspenseInfiniteQuery로 그 데이터를 읽기 전에, 부모에서 먼저 요청을 걸어 둔다.
usePrefetchQuery의 무한 쿼리 판이다. 옵션은 infiniteQueryOptions와 같은 모양(queryKey, queryFn, initialPageParam, getNextPageParam)을 받고, 아무것도 돌려주지 않는다(void).
usePrefetchInfiniteQuery({
queryKey: ['posts'],
queryFn: fetchPostsPage,
initialPageParam: 1,
getNextPageParam: (lastPage) => lastPage.nextPage,
})
무슨 일이 일어나나
이 훅은 렌더 시점에 부수 효과로 프리페치를 건다. Suspense를 쓰면 자식이 useSuspenseInfiniteQuery로 데이터를 읽으려는 순간 아직 로딩 중이면 그 자식이 suspend되는데, 부모에서 미리 요청을 걸어 두면 자식이 마운트될 때쯤 데이터가 이미 캐시에 들어와 워터폴(부모가 뜨고 나서야 자식이 요청을 시작하는 지연)을 줄인다.
데이터를 돌려주지 않는 게 핵심이다. 이 훅은 "캐시를 데워 두는" 역할만 하고, 실제 소비는 자식의 useSuspenseInfiniteQuery가 같은 키로 한다.
사용법
부모에서 프리페치, 자식에서 소비. 부모는 Suspense 경계를 두고, 그 안쪽 자식이 같은 키로 데이터를 읽는다.
import {
usePrefetchInfiniteQuery,
useSuspenseInfiniteQuery,
} from '@tanstack/react-query'
import { Suspense } from 'react'
function PostsPage() {
// 렌더 중 미리 요청 → 자식이 suspend될 때 데이터가 준비돼 있음
usePrefetchInfiniteQuery({
queryKey: ['posts'],
queryFn: fetchPostsPage,
initialPageParam: 1,
getNextPageParam: (lastPage) => lastPage.nextPage,
})
return (
<Suspense fallback={<Spinner />}>
<PostList />
</Suspense>
)
}
function PostList() {
const { data } = useSuspenseInfiniteQuery({
queryKey: ['posts'],
queryFn: fetchPostsPage,
initialPageParam: 1,
getNextPageParam: (lastPage) => lastPage.nextPage,
})
return <>{data.pages.flatMap((p) => p.items).map((post) => <Row key={post.id} {...post} />)}</>
}
실무 예시
무한 목록을 Suspense로 스트리밍할 때, 목록 컴포넌트가 마운트되기 전에 첫 페이지를 미리 걸어 첫 화면 지연을 줄이는 경우다. 부모와 자식이 같은 옵션을 쓰므로 infiniteQueryOptions로 묶어 두면 중복이 사라진다.
import { postsInfinite } from './postsInfinite' // infiniteQueryOptions(...)
function PostsPage() {
usePrefetchInfiniteQuery(postsInfinite)
return (
<Suspense fallback={<Spinner />}>
<PostList />
</Suspense>
)
}
왜 중요한가
usePrefetchInfiniteQuery는 Suspense 기반 무한 쿼리에서 워터폴을 줄이는 좁은 최적화 도구다. Suspense를 쓰지 않거나 무한 쿼리가 없다면 마주칠 일이 없고, 필요할 때도 queryClient.prefetchInfiniteQuery를 라우트 로더에서 부르는 편이 더 흔하다. 이 훅의 자리는 "컴포넌트 렌더 안에서 선언적으로 프리페치하고 싶은 Suspense 시나리오"로 한정된다.
Reference