Skip to content

Commit ca335de

Browse files
authored
fix(useInfiniteQuery): fix infinite re-renders when select produced a new result (TanStack#3081)
* fix(useInfiniteQuery): fix infinite re-renders when select produced a new result by correctly forwarding notifyOptions * fix(useInfiniteQuery): fix suspense test asserting the length of 3 seems wrong here and was likely only necessary because we triggered one too many re-renders before this fix :)
1 parent 0f00cda commit ca335de

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

src/core/infiniteQueryObserver.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import type {
66
InfiniteQueryObserverResult,
77
} from './types'
88
import type { QueryClient } from './queryClient'
9-
import { ObserverFetchOptions, QueryObserver } from './queryObserver'
9+
import {
10+
NotifyOptions,
11+
ObserverFetchOptions,
12+
QueryObserver,
13+
} from './queryObserver'
1014
import {
1115
hasNextPage,
1216
hasPreviousPage,
@@ -67,12 +71,16 @@ export class InfiniteQueryObserver<
6771
TError,
6872
TData,
6973
TQueryData
70-
>
74+
>,
75+
notifyOptions?: NotifyOptions
7176
): void {
72-
super.setOptions({
73-
...options,
74-
behavior: infiniteQueryBehavior(),
75-
})
77+
super.setOptions(
78+
{
79+
...options,
80+
behavior: infiniteQueryBehavior(),
81+
},
82+
notifyOptions
83+
)
7684
}
7785

7886
getOptimisticResult(

src/react/tests/suspense.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ describe("useQuery's in Suspense mode", () => {
103103
fireEvent.click(rendered.getByText('next'))
104104
await sleep(10)
105105

106-
expect(states.length).toBe(3)
107-
expect(states[2]).toMatchObject({
106+
expect(states.length).toBe(2)
107+
expect(states[1]).toMatchObject({
108108
data: { pages: [2], pageParams: [undefined] },
109109
status: 'success',
110110
})

src/react/tests/useInfiniteQuery.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
QueryClient,
1616
QueryCache,
1717
QueryFunctionContext,
18+
InfiniteData,
1819
} from '../..'
1920

2021
interface Result {
@@ -293,6 +294,41 @@ describe('useInfiniteQuery', () => {
293294
})
294295
})
295296

297+
it('should be able to select a new result and not cause infinite renders', async () => {
298+
const key = queryKey()
299+
const states: UseInfiniteQueryResult<{ count: number; id: number }>[] = []
300+
let selectCalled = 0
301+
302+
function Page() {
303+
const state = useInfiniteQuery(key, () => ({ count: 1 }), {
304+
select: React.useCallback((data: InfiniteData<{ count: number }>) => {
305+
selectCalled++
306+
return {
307+
pages: data.pages.map(x => ({ ...x, id: Math.random() })),
308+
pageParams: data.pageParams,
309+
}
310+
}, []),
311+
})
312+
states.push(state)
313+
return null
314+
}
315+
316+
renderWithClient(queryClient, <Page />)
317+
318+
await sleep(20)
319+
320+
expect(states.length).toBe(2)
321+
expect(selectCalled).toBe(1)
322+
expect(states[0]).toMatchObject({
323+
data: undefined,
324+
isSuccess: false,
325+
})
326+
expect(states[1]).toMatchObject({
327+
data: { pages: [{ count: 1 }] },
328+
isSuccess: true,
329+
})
330+
})
331+
296332
it('should be able to reverse the data', async () => {
297333
const key = queryKey()
298334
const states: UseInfiniteQueryResult<number>[] = []

0 commit comments

Comments
 (0)