공식문서 : https://tanstack.com/query/v4/docs/guides/query-invalidation
쿼리를 다시 fetch하기 전에 쿼리가 stale하게 될때까지 기다리는것이 항상 동작하는것은 아니다. 특히 유저가 수행한 작업으로 인해 쿼리의 데이터가 오래되었다는 사실을 알고 있는 경우에는 더욱 그렇다. 이를 위해 QueryClient에는 지능적으로 쿼리를 stale하다고 표시하고 잠재적으로 refetch할 수 있는 invalidateQueries
메서드가 있다.
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries(['todos'])
참고 : 정규화된 캐시를 사용하는 다른 라이브러리가 명령적으로 또는 스키마 추론을 통해 새로운 데이터로 로컬 쿼리를 업데이트하려고 하는 경우, React Query는 정규화된 캐시를 유지관리 하는데 수반되는 수동 작업을 피하고 대신 targeted invalidation, 백그라운드 refetch 및 궁극적으로 원자성 업데이트를 규정할 수 있는 도구를 제공한다.
쿼리가 invalidteQueries
로 무효화되면 다음 두가지 일이 발생한다 :
useQuery
또는 관련 hook들에서 사용중인 모든 staleTime
설정을 재정의한다.useQuery
또는 관련 hook들을 통해 쿼리가 렌더링되는 경우, 백그라운드에서도 refetch된다.invalidateQueries
invalidateQueries
및 removeQueries
(및 부분 쿼리 매칭을 지원하는 다른 API)와 같은 API를 사용할 때, 접두사를 기준으로 여러 쿼리들을 매치시키거나, 매우 구체적이고 정확한 쿼리를 일치시킬 수 있다. 사용할 수 있는 필터 유형에 대한 자세한 내용은 Query Filters를 참고해라.
이 예제에서는, todos
접두사를 사용하여 쿼리 키에서 todos
로 시작하는 쿼리들을 무효화할 수 있다.
import { useQuery, useQueryClient } from '@tanstack/react-query'
// Get QueryClient from the context
const queryClient = useQueryClient()
queryClient.invalidateQueries(['todos'])
// Both queries below will be invalidated
const todoListQuery = useQuery(['todos'], fetchTodoList)
const todoListQuery = useQuery(['todos', { page: 1 }], fetchTodoList)
더 구체적인 쿼리 키를 invalidateQueries
메서드에 전달하여 특정 변수가 있는 쿼리를 무효화할 수도 있다.
queryClient.invalidateQueries(['todos', { type: 'done' }])
// The query below will be invalidated
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery(['todos'], fetchTodoList)
invalidateQueries
API는 매우 유연하므로, 더 이상 변수나 하위 키들이 없는 todos
쿼리들만 무효화하고싶다면, invalidateQueries
메서드에 exact:true
옵션을 전달하면 된다 :
queryClient.invalidateQueries(['todos'], { exact: true })
// The query below will be invalidated
const todoListQuery = useQuery(['todos'], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
더 세분화하고 싶다면, invalidateQueries
메서드에 predicate 함수를 전달할 수 있다. 이 함수는 쿼리 캐시에서 각 Query
인스턴스를 수신하고 해당 쿼리를 무효화할지 여부에 대한 true
또는 false
를 반환할 수 있도록 한다.
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)