[TanStakQuery] Query Invalidation

Jeris·2023년 5월 22일
0

쿼리가 다시 fetched되기 전에 쿼리가 stale될 때까지 기다리는 것이 항상 효과적인 것은 아니며, 특히 사용자가 수행한 작업으로 인해 쿼리의 데이터가 오래되었다는 사실을 알고 있는 경우에는 더욱 그렇습니다. 이를 위해 QueryClient에는 쿼리를 오래된 것으로 지능적으로 표시하고 잠재적으로 다시 가져올 수 있는 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는 정규화된 캐시를 유지하는 데 따르는 수작업을 피할 수 있는 도구를 제공하며, 대신 targeted invalidation, background-refetching 및 궁극적으로 atomic 업데이트를 규정합니다."

쿼리가 invalidateQueries로 invalidation되면 두 가지 일이 발생합니다:

  • stale으로 표시됩니다. 이 stale 상태는 useQuery 또는 관련 훅에서 사용 중인 모든 staleTime 구성을 재정의합니다.
  • 쿼리가 현재 useQuery 또는 관련 훅을 통해 렌더링되고 있는 경우 백그라운드에서도 refetched됩니다.

아래 예시에서, todos 접두사를 사용하여 쿼리 키에 todos로 시작하는 모든 쿼리를 invalidate할 수 있습니다:

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,
})

특정 변수가 포함된 쿼리를 invalidate하려면 보다 구체적인 쿼리 키를 invalidateQueries 메서드에 전달하여 invalidate할 수도 있습니다:

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는 매우 유연하기 때문에 더 이상 변수나 하위 키가 없는 모든 쿼리만 invlidate하려는 경우에도 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 메서드에 전달할 수 있습니다. 이 함수는 쿼리 캐시에서 각 쿼리 인스턴스를 수신하고 해당 쿼리를 invlidate할지 여부에 대해 참 또는 거짓을 리턴할 수 있습니다:

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,
})

Reference

profile
job's done

0개의 댓글