QueryClient.isFetching and useIsFetching accept a fetchStatus filter and ignore it
Maintainer antworten meist innerhalb von 1 Tag
@Apu-Emdad arbeitet bereits daran.
Seit 14.10.2026.
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 78/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- react, typescript
- Bereich
- backend-api-design
Rechercherichtung
Beginne in packages/query-core/src/queryClient.ts, wo der Issue die Spread-Operation und das Überschreiben von fetchStatus in isFetching benennt; verfolge anschließend, wie useIsFetching seine Filter weitergibt. Lies die zugehörigen Tests für QueryClient.isFetching und useIsFetching und ergänze Abdeckung für die gemeldeten pausierten und inaktiven Fälle. Die Arbeit ist abgeschlossen, wenn die API den Filter entweder berücksichtigt oder ihn in ihren Typen ablehnt und Verhalten und Dokumentation übereinstimmen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the bug
QueryFilters has a fetchStatus?: FetchStatus field, and FetchStatus is 'fetching' | 'paused' | 'idle', so isFetching({ fetchStatus: 'paused' }) type-checks. It has no effect: QueryClient.isFetching spreads the filters it is given and then writes its own fetchStatus over them, so the argument is discarded for every value, not only 'paused'.
QueryCache.findAll honours the same filter correctly, which makes the difference easy to miss — the filter works through one entry point and is silently dropped through the other.
Minimal reproduction
import { QueryClient } from '@tanstack/query-core'
const client = new QueryClient()
const queryKey = ['session']
const cache = client.getQueryCache()
const query = cache.build(client, { queryKey, queryFn: async () => 'x' })
query.setState({ fetchStatus: 'paused' })
console.log(cache.find({ queryKey })?.state.fetchStatus) // 'paused'
console.log(cache.findAll({ queryKey, fetchStatus: 'paused' }).length) // 1
console.log(client.isFetching({ queryKey, fetchStatus: 'paused' })) // 0
console.log(client.isFetching({ queryKey, fetchStatus: 'idle' })) // 0
Expected / actual
| call | expected | actual |
|---|---|---|
findAll({ fetchStatus: 'paused' }).length |
1 | 1 |
isFetching({ fetchStatus: 'paused' }) |
1, or a type error | 0 |
isFetching({ fetchStatus: 'idle' }) |
1, or a type error | 0 |
Either outcome would be fine. What is awkward is a public, typed, documented parameter that is accepted and does nothing.
Cause
packages/query-core/src/queryClient.ts:
isFetching(filters) {
return this.#queryCache.findAll({ ...filters, fetchStatus: 'fetching' }).length
}
useIsFetching forwards its filters to this method, so it behaves the same way.
Why it came up
An app that asks "is this query still waiting on the network" wants paused to count: a lookup held because the browser is offline, or because the window is unfocused and the retry is deferred, has not answered yet. Reading it through useIsFetching({ queryKey, fetchStatus: 'paused' }) compiles and quietly answers 0, so the UI treats a waiting query as a settled one. In our case a page showed a "not found" state to someone whose session lookup was merely paused.
The workaround is to subscribe to the cache and use findAll directly, which works but means reimplementing what useIsFetching exists to provide.
Possible resolutions
In rough order of how little they change:
- Type it out — omit
fetchStatusfrom the filters these two accept, so passing it is a compile error, and say in the reference that they count fetching queries only. - Honour it — use the caller's
fetchStatuswhen one is given and default to'fetching'otherwise. This changes behaviour for anyone currently passing a value and relying on it being ignored, which seems unlikely but is a real semver consideration. - Leave the behaviour and document it — note on
useIsFetchingandQueryClient.isFetchingthatfetchStatusis fixed, and point atgetQueryCache().findAllfor other statuses.
Happy to send a PR for whichever you prefer.
Related
- Discussion #6756 proposes a built-in
queryClient.isPaused/useIsPaused, and its example hook uses the same spread-then-override pattern in user code. If that proposal is the intended answer, this is the part of it that bites today — and option 1 or 3 above would stop the current API misleading people in the meantime. - #7559 and #8531 are about
isFetchingreporting the wrong thing for fetching queries; this is narrower, about a filter argument being inert.
Environment
@tanstack/query-core5.104.1- Node 26.11.1, TypeScript 6.0.3
- Reproduced with
query-corealone, so no framework adapter is involved
- Vorherrschende Sprache
- TypeScript
- Sterne
- 50.4k
- Forks
- 4.2k
- Ø Merge
- 9 Std. 3 Min.
- Gemergte PRs (30 T.)
- 426
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus TanStack/query
-
solid-query: STRICT_READ_UNTRACKED on Solid 2 — client()/options() read in component body (useMutation, useBaseQuery)Evtl. wieder frei @LeonxLJX hat das vor 42 Tagen übernommen, und es ist kein Pull Request offen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
TanStack/query#11358 · 2 Kommentare · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
-
solid-query: switching the queryClient accessor strands the new client's cache (subscription stays on the old observer)Evtl. vergeben @MaNaN1803 hat das vor 85 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
TanStack/query#11106 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
angular-query: migrate-from-experimental schematic crashes with 'Path ... is a file' on a .js subpath importEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 45/100
Maintainer antworten meist innerhalb von 1 Tag
-
solid-query 6.0.0-rc.5: onCacheEvent throws NotReadyError during a Solid 2 (rc.14+) transition landingEvtl. vergeben @UzumakiODZ hat das vor 1 Tag übernommen. Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 28/100
TanStack/query#12031 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Explicit gcTime schedules a GC timer during SSR, retaining the whole render in memoryEvtl. vergeben @AdzerKI hat das vor 1 Tag übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 25/100
Maintainer antworten meist innerhalb von 1 Tag
Ähnliche Issues
-
Add: Yemen Education SDOffenstreams:add
Schwierigkeit 2/5 Unter einer Stunde Anfängerfreundlichkeit 70/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
apache/rocketmq-dashboard#6872 ·
Maintainer antworten meist innerhalb von 3 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
interledger/publisher-tools#931 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
ARTPARK-SAHAI-ORG/calibrate-frontend#727 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
fab-geocommuns/RNB-site#539 ·
Maintainer antworten meist innerhalb von 2 Tagen