Skip to content

Commit 53cdfce

Browse files
authored
fix(core): do not invoke combine in constructor (#7215)
because the component might suspend, in which case we have nothing to combine
1 parent a4d843a commit 53cdfce

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

packages/query-core/src/queriesObserver.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,21 @@ export class QueriesObserver<
3939
#result!: Array<QueryObserverResult>
4040
#queries: Array<QueryObserverOptions>
4141
#observers: Array<QueryObserver>
42-
#options?: QueriesObserverOptions<TCombinedResult>
43-
#combinedResult!: TCombinedResult
42+
#combinedResult?: TCombinedResult
4443

4544
constructor(
4645
client: QueryClient,
4746
queries: Array<QueryObserverOptions>,
48-
options?: QueriesObserverOptions<TCombinedResult>,
47+
_options?: QueriesObserverOptions<TCombinedResult>,
4948
) {
5049
super()
5150

5251
this.#client = client
5352
this.#queries = []
5453
this.#observers = []
54+
this.#result = []
5555

56-
this.#setResult([])
57-
this.setQueries(queries, options)
58-
}
59-
60-
#setResult(value: Array<QueryObserverResult>) {
61-
this.#result = value
62-
this.#combinedResult = this.#combineResult(value, this.#options?.combine)
56+
this.setQueries(queries)
6357
}
6458

6559
protected onSubscribe(): void {
@@ -87,11 +81,10 @@ export class QueriesObserver<
8781

8882
setQueries(
8983
queries: Array<QueryObserverOptions>,
90-
options?: QueriesObserverOptions<TCombinedResult>,
84+
_options?: QueriesObserverOptions<TCombinedResult>,
9185
notifyOptions?: NotifyOptions,
9286
): void {
9387
this.#queries = queries
94-
this.#options = options
9588

9689
notifyManager.batch(() => {
9790
const prevObservers = this.#observers
@@ -117,7 +110,7 @@ export class QueriesObserver<
117110
}
118111

119112
this.#observers = newObservers
120-
this.#setResult(newResult)
113+
this.#result = newResult
121114

122115
if (!this.hasListeners()) {
123116
return
@@ -137,8 +130,8 @@ export class QueriesObserver<
137130
})
138131
}
139132

140-
getCurrentResult(): TCombinedResult {
141-
return this.#combinedResult
133+
getCurrentResult(): Array<QueryObserverResult> {
134+
return this.#result
142135
}
143136

144137
getQueries() {
@@ -254,7 +247,7 @@ export class QueriesObserver<
254247
#onUpdate(observer: QueryObserver, result: QueryObserverResult): void {
255248
const index = this.#observers.indexOf(observer)
256249
if (index !== -1) {
257-
this.#setResult(replaceAt(this.#result, index, result))
250+
this.#result = replaceAt(this.#result, index, result)
258251
this.#notify()
259252
}
260253
}

packages/react-query/src/__tests__/useSuspenseQueries.test.tsx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { act, render } from '@testing-library/react'
1111
import * as React from 'react'
1212
import { useSuspenseQueries } from '..'
13-
import { createQueryClient, sleep } from './utils'
13+
import { createQueryClient, queryKey, renderWithClient, sleep } from './utils'
1414
import type { UseSuspenseQueryOptions } from '..'
1515

1616
type NumberQueryOptions = UseSuspenseQueryOptions<number>
@@ -141,4 +141,45 @@ describe('useSuspenseQueries', () => {
141141
expect(onQueriesResolution).toHaveBeenCalledTimes(2)
142142
expect(onQueriesResolution).toHaveBeenLastCalledWith([3, 4, 5, 6])
143143
})
144+
145+
it('should only call combine after resolving', async () => {
146+
const spy = vi.fn()
147+
const key = queryKey()
148+
149+
function Page() {
150+
const data = useSuspenseQueries({
151+
queries: [1, 2, 3].map((value) => ({
152+
queryKey: [...key, { value }],
153+
queryFn: async () => {
154+
await sleep(value * 10)
155+
return { value: value * 10 }
156+
},
157+
})),
158+
combine: (result) => {
159+
spy(result)
160+
return 'data'
161+
},
162+
})
163+
164+
return <h1>{data}</h1>
165+
}
166+
167+
const rendered = renderWithClient(
168+
queryClient,
169+
<React.Suspense fallback="loading...">
170+
<Page />
171+
</React.Suspense>,
172+
)
173+
174+
await act(() => vi.advanceTimersByTimeAsync(10))
175+
176+
rendered.getByText('loading...')
177+
178+
expect(spy).not.toHaveBeenCalled()
179+
180+
await act(() => vi.advanceTimersByTimeAsync(30))
181+
rendered.getByText('data')
182+
183+
expect(spy).toHaveBeenCalled()
184+
})
144185
})

0 commit comments

Comments
 (0)