Infinite loading with useInfiniteQuery promise + React use hook in Suspense
Describe the bug
I'm experiencing an infinite loading issue when using useInfiniteQuery's promise with React's use hook inside a Suspense boundary. Setup:
Using useInfiniteQuery with experimental_prefetchInRender: true Returning the promise property from the query Consuming the promise with React's use() hook Component is wrapped in a <Suspense> boundary
Issue:
The page enters an infinite loading state The UI renders correctly on screen Chrome DevTools Network tab shows: "Caution: request is not finished yet" in the document request The request never completes
export default function DetailReviewWrapper({ pid, userId }: DetailReviewProps) {
const { infoData, observerRef, isFetchingNextPage, refetch, promise } = useReviewListInfinity({
userId,
pid,
})
return (
<Suspense fallback={<DetailReviewLoading />}>
<DetailReview
pid={pid}
userId={userId}
promise={promise}
refetch={refetch}
isFetchingNextPage={isFetchingNextPage}
observerRef={observerRef}
/>
</Suspense>
)
}
export default function DetailReview({
pid,
userId,
promise,
refetch,
isFetchingNextPage,
observerRef,
}: DetailReviewProps) {
const data = use(promise)
return (
<>
<section>
<ReviewListView
userId={userId}
pid={pid}
data={data?.list || []}
className={cn('review-list')}
refetch={refetch}
showPoint
/>
{isFetchingNextPage && <Loading />}
<div ref={observerRef} />
</section>
export function useReviewListInfinity(params: UseReviewListInfinityProps) {
const section = useSearchParams().get('contentType') as SectionType
const orderType = useRecoilValue(commentOrderState)
const filterType = useRecoilValue(filterTypeState)
const { fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, refetch, promise } = useInfiniteQuery({
queryKey: [REVIEW_LIST_KEY, params, orderType, filterType, section],
queryFn: ({ pageParam = 1 }) =>
getReviewApi({
uid: params.userId,
pid: params.pid,
section,
pageInfo: {
curPage: pageParam,
pageSize: 20,
},
orderType: orderType === 'RECOMMENDED' ? 'like' : 'date',
filterType,
}),
select: (data) => {
return {
list: data.pages.flatMap((page) => page.data.list),
info: data.pages[0].data.info,
}
},
getNextPageParam: (lastPage) => {
const nextPage = lastPage.data.pageInfo.curPage + 1
return nextPage <= lastPage.data.pageInfo.pageCount ? nextPage : undefined
},
initialPageParam: 1,
})
const { observerRef } = useIntersectionObserver({
onScroll: () => {
if (hasNextPage && !isFetchingNextPage) {
fetchNextPage()
}
},
})
return {
infoData,
isLoading,
isFetchingNextPage,
observerRef,
refetch,
promise,
}
}
const getQueryClient = (): QueryClient =>
new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchInterval: false,
refetchOnReconnect: true,
refetchOnMount: true,
staleTime: Infinity,
gcTime: Infinity,
retry: false,
experimental_prefetchInRender: true,
},
},
})
Your minimal, reproducible example
No response
Steps to reproduce
No response
Expected behavior
he page request should complete when the promise is fulfilled.
How often does this bug happen?
None
Screenshots or Videos
Platform
OS: mac os
Browser: chrome
next.js : 14.2 react : 18
Tanstack Query adapter
None
TanStack Query version
5.8.1
TypeScript version
5.8.3
Additional context
No response
please show a minimal runnable reproduction; at best you just swap out whatever you do in your queryFn with Promise.resolve(someStaticJson) to rule out any network issues.