Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions docs/framework/react/guides/query-invalidation.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ When a query is invalidated with `invalidateQueries`, two things happen:
- It is marked as stale. This stale state overrides any `staleTime` configurations being used in `useQuery` or related hooks
- If the query is currently being rendered via `useQuery` or related hooks, it will also be refetched in the background

> **Important:** By default, `invalidateQueries` will immediately refetch *only active queries*—those currently used by mounted components. Inactive queries (cached but not in use) are marked as stale but will not be refetched until they become active again (e.g., when a component utilizing the query mounts). This means that calling `invalidateQueries` without additional options does *not* guarantee all matching queries are refetched immediately.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is pretty much the same as the two points above are also saying. The second one only says “is currently being rendered via useQuery or related hooks”, maybe this could be re-worded to “active queries”, and then explained what an active query is.


## Query Matching with `invalidateQueries`

When using APIs like `invalidateQueries` and `removeQueries` (and others that support partial query matching), you can match multiple queries by their prefix, or get really specific and match an exact query. For information on the types of filters you can use, please see [Query Filters](../filters.md#query-filters).
Expand All @@ -41,12 +44,12 @@ queryClient.invalidateQueries({ queryKey: ['todos'] })

// Both queries below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
queryKey: ['todos'],
queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
queryKey: ['todos', { page: 1 }],
queryFn: fetchTodoList,
queryKey: ['todos', { page: 1 }],
queryFn: fetchTodoList,
})
```

Expand Down Expand Up @@ -119,8 +122,8 @@ const todoListQuery = useQuery({

// The query below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { version: 10 }],
queryFn: fetchTodoList,
queryKey: ['todos', { version: 10 }],
queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
Expand All @@ -131,3 +134,20 @@ const todoListQuery = useQuery({
```

[//]: # 'Example5'

By default, `invalidateQueries` only refetches active queries. If you want to refetch **all matching queries**, including those currently inactive in the cache, you need to explicitly set the `refetchType` (or `type`) option to `'all'`:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is partially wrong. setting type: 'all' wouldn't achieve that. It's also the default behaviour.


[//]: # 'Example6'

```tsx
queryClient.invalidateQueries({
queryKey: ['todos'],
refetchType: 'all' // or type: 'all'
});
```

[//]: # 'Example6'

This forces every matching query—active or inactive—to be refetched immediately.

> 🧠 **Note:** The default behavior (`refetchType: 'active'`) helps avoid unnecessary network requests. But if you're triggering an invalidation after a mutation that affects *all clients or views*, make sure to use `refetchType: 'all'` to keep all query caches up to date.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand that sentence - what is “all clients or views” referring to? Imo there’s really no need to set refetchType: 'all', as it will likely lead to overfetching. It's something we have documented in the API docs, but I don’t think we need to emphasize on this with a guide.

Loading