diff --git a/packages/query-core/src/queriesObserver.ts b/packages/query-core/src/queriesObserver.ts index 6458f208da..b8068ec491 100644 --- a/packages/query-core/src/queriesObserver.ts +++ b/packages/query-core/src/queriesObserver.ts @@ -118,21 +118,22 @@ export class QueriesObserver< observer.getCurrentResult(), ) + const hasLengthChange = prevObservers.length !== newObservers.length const hasIndexChange = newObservers.some( (observer, index) => observer !== prevObservers[index], ) + const hasStructuralChange = hasLengthChange || hasIndexChange - const hasResultChange = - prevObservers.length === newObservers.length && !hasIndexChange - ? newResult.some((result, index) => { - const prev = this.#result[index] - return !prev || !shallowEqualObjects(result, prev) - }) - : true + const hasResultChange = hasStructuralChange + ? true + : newResult.some((result, index) => { + const prev = this.#result[index] + return !prev || !shallowEqualObjects(result, prev) + }) - if (!hasIndexChange && !hasResultChange) return + if (!hasStructuralChange && !hasResultChange) return - if (hasIndexChange) { + if (hasStructuralChange) { this.#observers = newObservers } @@ -140,7 +141,7 @@ export class QueriesObserver< if (!this.hasListeners()) return - if (hasIndexChange) { + if (hasStructuralChange) { difference(prevObservers, newObservers).forEach((observer) => { observer.destroy() }) diff --git a/packages/react-query/src/__tests__/useQueries.test.tsx b/packages/react-query/src/__tests__/useQueries.test.tsx index b475bdadb6..19fbe1f7c3 100644 --- a/packages/react-query/src/__tests__/useQueries.test.tsx +++ b/packages/react-query/src/__tests__/useQueries.test.tsx @@ -1741,4 +1741,74 @@ describe('useQueries', () => { // still no extra calls to combine expect(spy).toHaveBeenCalledTimes(3) }) + + it('should not cause infinite re-renders when removing last query', async () => { + let renderCount = 0 + + function Page() { + const [queries, setQueries] = React.useState([ + { + queryKey: ['query1'], + queryFn: () => 'data1', + }, + { + queryKey: ['query2'], + queryFn: () => 'data2', + }, + ]) + renderCount++ + + const result = useQueries({ queries }) + + return ( +