React Query: Invalidate query caches
How to invalidate a query
You can use the invalidateQueries
method:
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries('todos')
// Invalidate every query with a key that starts with `todos` and that
// has some filters
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
Why / when to invalidate a query?
By default, React Query caches your queries and doesn’t refetch them until they become stale (because the configured cacheTime
has elapsed). This is great and helps keep your applications fast.
But sometimes the user will do something that will invalidate a previously cached query. For example, if the user adds a new todo item, you’ll want to invalidate the query cache that fetched the list of todos because you know the results of that query is now outdated:
import { useMutation, useQueryClient } from 'react-query'
const queryClient = useQueryClient()
// When this mutation succeeds, invalidate any queries with the `todos` or `reminders` query key
const mutation = useMutation(addTodo, {
onSuccess: () => {
queryClient.invalidateQueries('todos')
queryClient.invalidateQueries('reminders')
},
})
What invalidating a query does
- The query is marked as stale.
- If the query is currently being rendered (e.g., via
useQuery
), it will be refetched in the background.
Have fine-grained control over whether query is invalidated
You can pass a function as the predicate
option to have fine-grained control over whether the query is invalidated or not:
queryClient.invalidateQueries({
predicate: query =>
query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
})
// The query below will be invalidated
const todoListQuery = useQuery(['todos', { version: 20 }], fetchTodoList)
// The query below will be invalidated
const todoListQuery = useQuery(['todos', { version: 10 }], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery(['todos', { version: 5 }], fetchTodoList)
Sometimes you might want to directly update the query cache instead of invalidating queries
Alternatively, if your mutation updates an object on the server and the server responds with the updated object, you can use the server response to directly update your query cache (instead of invalidating and refetching a query):
const queryClient = useQueryClient()
const mutation = useMutation(editTodo, {
onSuccess: data => {
queryClient.setQueryData(['todo', { id: 5 }], data)
}
})
mutation.mutate({
id: 5,
name: 'Do the laundry',
})
// The query below will be updated with the response from the
// successful mutation
const { status, data, error } = useQuery(['todo', { id: 5 }], fetchTodoById)
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment