diff --git a/packages/query-core/src/__tests__/queryClient.test.tsx b/packages/query-core/src/__tests__/queryClient.test.tsx index b8f58e2ec7..0ad7baed30 100644 --- a/packages/query-core/src/__tests__/queryClient.test.tsx +++ b/packages/query-core/src/__tests__/queryClient.test.tsx @@ -1409,6 +1409,46 @@ describe('queryClient', () => { expect(queryFn2).toHaveBeenCalledTimes(2) }) + test('should not refetch disabled inactive queries even if "refetchType" is "all', async () => { + const queryFn = vi + .fn<(...args: Array) => string>() + .mockReturnValue('data1') + const observer = new QueryObserver(queryClient, { + queryKey: queryKey(), + queryFn: queryFn, + staleTime: Infinity, + enabled: false, + }) + const unsubscribe = observer.subscribe(() => undefined) + unsubscribe() + await queryClient.invalidateQueries({ + refetchType: 'all', + }) + expect(queryFn).toHaveBeenCalledTimes(0) + }) + + test('should not refetch inactive queries that have a skipToken queryFn even if "refetchType" is "all', async () => { + const key = queryKey() + const observer = new QueryObserver(queryClient, { + queryKey: key, + queryFn: skipToken, + staleTime: Infinity, + }) + + queryClient.setQueryData(key, 'data1') + + const unsubscribe = observer.subscribe(() => undefined) + unsubscribe() + + expect(queryClient.getQueryState(key)?.dataUpdateCount).toBe(1) + + await queryClient.invalidateQueries({ + refetchType: 'all', + }) + + expect(queryClient.getQueryState(key)?.dataUpdateCount).toBe(1) + }) + test('should cancel ongoing fetches if cancelRefetch option is set (default value)', async () => { const key = queryKey() const abortFn = vi.fn() diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts index 1160b1acfd..9850c75160 100644 --- a/packages/query-core/src/query.ts +++ b/packages/query-core/src/query.ts @@ -3,6 +3,7 @@ import { noop, replaceData, resolveEnabled, + skipToken, timeUntilStale, } from './utils' import { notifyManager } from './notifyManager' @@ -256,7 +257,14 @@ export class Query< } isDisabled(): boolean { - return this.getObserversCount() > 0 && !this.isActive() + if (this.getObserversCount() > 0) { + return !this.isActive() + } + // if a query has no observers, it should still be considered disabled if it never attempted a fetch + return ( + this.options.queryFn === skipToken || + this.state.dataUpdateCount + this.state.errorUpdateCount === 0 + ) } isStale(): boolean {