Problem
When RTK Query removes a cache entry via removeQueryResult (such as when invalidating a tag with zero subscribers), it completely deletes the query cache entry from state. This has an unintended side-effect:
- When a component resubscribes to that query, the query slice has no cache entry, so the
isLoading state does not correctly transition through isUninitialized -> isLoading = true -> data.
- Instead, it acts as if the query never existed; the state is not reset to
uninitialized, it's just gone.
Why it matters
This breaks the following:
isLoading is meant to only be true when no data exists and a fetch is in-flight (page is loading from empty state)
isFetching is meant for showing refetch/loading with already existing data
If a query entry is just deleted and not reset, subscribers cannot differentiate between a fresh initial loading state and a refresh/re-fetch. This can break loading-indicator logic and UI expectations.
Code reference
// buildSlice.ts
removeQueryResult: {
reducer(
draft,
{
payload: { queryCacheKey },
}: PayloadAction<QuerySubstateIdentifier>,
) {
delete draft[queryCacheKey]
},
...
}
What should happen instead:
- reset the entry to status
STATUS_UNINITIALIZED (not delete), so that the next subscription triggers the expected state flow
Steps to reproduce
- Create a query and subscribe to it (shows
isLoading=true on initial mount)
- Invalidate the query with no active subscribers (
removeQueryResult fires)
- Subscribe again. The entry is missing from state, so initial transitions do not occur and
isLoading is not true as expected.
Expected behavior:
Deleting a query result when there are no subscribers should reset the entry to uninitialized (not delete), ensuring the correct isLoading/isFetching state transitions.
Links/References
Labels
RTK-Query, bug
Problem
When RTK Query removes a cache entry via
removeQueryResult(such as when invalidating a tag with zero subscribers), it completely deletes the query cache entry from state. This has an unintended side-effect:isLoadingstate does not correctly transition throughisUninitialized -> isLoading = true -> data.uninitialized, it's just gone.Why it matters
This breaks the following:
isLoadingis meant to only betruewhen no data exists and a fetch is in-flight (page is loading from empty state)isFetchingis meant for showing refetch/loading with already existing dataIf a query entry is just deleted and not reset, subscribers cannot differentiate between a fresh initial loading state and a refresh/re-fetch. This can break loading-indicator logic and UI expectations.
Code reference
What should happen instead:
STATUS_UNINITIALIZED(not delete), so that the next subscription triggers the expected state flowSteps to reproduce
isLoading=trueon initial mount)removeQueryResultfires)isLoadingis nottrueas expected.Expected behavior:
Deleting a query result when there are no subscribers should reset the entry to
uninitialized(not delete), ensuring the correct isLoading/isFetching state transitions.Links/References
Labels
RTK-Query,bug