무엇
InfiniteQueryObserver는 무한 쿼리를 구독해 상태 변화를 받는 저수준 클래스다. QueryObserver의 무한 버전이고, useInfiniteQuery가 내부에서 이걸 쓴다.
옵션은 useInfiniteQuery에 넘기는 것과 똑같다. 페이지를 이어 붙이는 무한 쿼리라서, 다음 페이지 파라미터를 구하는 getNextPageParam과 첫 페이지 파라미터인 initialPageParam이 필요하다.
const observer = new InfiniteQueryObserver(queryClient, {
queryKey: ['posts'],
queryFn: fetchPosts,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCursor,
})
무슨 일이 일어나나
QueryObserver가 쿼리 하나를 보는 것과 같은 방식으로, InfiniteQueryObserver는 여러 페이지가 쌓인 무한 쿼리를 본다. 캐시에 저장된 페이지 목록(data.pages)과 페이지 파라미터 목록을 읽어 현재 결과를 만들고, getNextPageParam으로 다음에 가져올 파라미터를 계산한다. 더 가져올 페이지가 있는지(hasNextPage)도 여기서 판단한다.
React 어댑터인 useInfiniteQuery는 이 옵저버를 하나 만들어 구독하고, 상태가 바뀔 때마다 리렌더를 일으킨다. 옵저버 자체는 프레임워크를 모른다.
사용법
옵저버를 만들고 subscribe로 결과를 듣는다. subscribe는 구독 해제 함수를 돌려준다.
import { InfiniteQueryObserver, QueryClient } from '@tanstack/query-core'
const queryClient = new QueryClient()
const observer = new InfiniteQueryObserver(queryClient, {
queryKey: ['posts'],
queryFn: fetchPosts,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCursor,
})
const unsubscribe = observer.subscribe((result) => {
console.log(result.data?.pages, result.hasNextPage)
})
unsubscribe()
실무 예시
거의 언제나 useInfiniteQuery를 쓴다. InfiniteQueryObserver를 직접 만드는 건 React 밖에서 무한 쿼리 상태가 필요한 특수한 통합에 한정된다 — 그때도 위 형태 그대로, 옵션만 useInfiniteQuery와 맞춰 넘긴다.
왜 중요한가
InfiniteQueryObserver는 무한 쿼리의 내부 엔진이지만, 개발자가 직접 부를 일은 거의 없다. useInfiniteQuery가 대신 써 주기 때문이다. 알아 두면 무한 쿼리가 어떻게 페이지를 쌓고 다음 페이지를 판단하는지 그림이 잡히는 정도의 값이 있다. 직접 쓰는 건 React가 없는 환경에서 무한 쿼리를 다뤄야 하는 드문 경우뿐이다.
Reference