쿼리 무효화
쿼리를 다시 가져오기 전에 stale 상태가 될 때까지 기다리는 방식이 항상 효과적인 것은 아닙니다. 특히 사용자가 수행한 작업으로 인해 쿼리 데이터가 오래되었다는 사실을 확실히 알고 있는 경우에는 더욱 그렇습니다. 이를 위해 QueryClient에는 쿼리를 지능적으로 stale 상태로 표시하고 필요에 따라 다시 가져올 수도 있게 해주는 invalidateQueries 메서드가 있습니다!
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries({ queryKey: ['todos'] })
참고: 정규화된 캐시를 사용하는 다른 라이브러리는 명령형 방식이나 스키마 추론을 통해 새 데이터로 로컬 쿼리를 업데이트하려고 하지만, TanStack Query는 정규화된 캐시를 유지하는 데 따르는 수작업을 피할 수 있는 도구를 제공하고 대신 표적 무효화, 백그라운드 다시 가져오기, 그리고 궁극적으로 원자적 업데이트를 권장합니다.
invalidateQueries로 쿼리를 무효화하면 다음 두 가지가 발생합니다:
- stale 상태로 표시됩니다. 이 stale 상태는
useQuery또는 관련 훅에서 사용되는 모든staleTime구성을 재정의합니다 - 현재
useQuery또는 관련 훅을 통해 쿼리를 렌더링하고 있다면 백그라운드에서도 다시 가져옵니다
invalidateQueries를 사용한 쿼리 일치
invalidateQueries 및 removeQueries처럼 API를 사용할 때(그리고 부분 쿼리 일치를 지원하는 다른 항목을 사용할 때) 접두사로 여러 쿼리를 일치시키거나 매우 구체적으로 정확한 쿼리 하나를 일치시킬 수 있습니다. 사용할 수 있는 필터 유형에 관한 정보는 쿼리 필터를 참조하세요.
이 예제에서는 todos 접두사를 사용하여 쿼리 키가 todos로 시작하는 모든 쿼리를 무효화할 수 있습니다:
import { useQuery, useQueryClient } from '@tanstack/react-query'
// Get QueryClient from the context
const queryClient = useQueryClient()
queryClient.invalidateQueries({ queryKey: ['todos'] })
// Both queries below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
queryKey: ['todos', { page: 1 }],
queryFn: fetchTodoList,
})
invalidateQueries 메서드에 더 구체적인 쿼리 키를 전달하면 특정 변수가 있는 쿼리도 무효화할 수 있습니다:
queryClient.invalidateQueries({
queryKey: ['todos', { type: 'done' }],
})
// The query below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { type: 'done' }],
queryFn: fetchTodoList,
})
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
invalidateQueries API는 매우 유연하므로, 변수나 하위 키가 더 이상 없는 todos 쿼리만**** 무효화하려는 경우에도 invalidateQueries 메서드에 exact: true 옵션을 전달할 수 있습니다:
queryClient.invalidateQueries({
queryKey: ['todos'],
exact: true,
})
// The query below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { type: 'done' }],
queryFn: 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({
queryKey: ['todos', { version: 20 }],
queryFn: fetchTodoList,
})
// The query below will be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { version: 10 }],
queryFn: fetchTodoList,
})
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
queryKey: ['todos', { version: 5 }],
queryFn: fetchTodoList,
})