Frontend/React

[Tanstack Query] invalidateQueries 무효화 범위

khakhalog 2024. 1. 12. 16:22

invalidateQueries는 POST, PATCH, DELETE, .. 등의 요청이 완료된 이후 새롭게 데이터를 페칭해야할 때 캐싱된 쿼리를 무효화하는 메서드입니다.

기본적으로 queryKey와 일치하는 모든 쿼리를 즉시 유효하지 않은 것으로 표시하고 active한 상태의 쿼리는 refetch합니다.

무효화시키고 싶은 queryKey를 매칭해주는 방식은 여러가지 존재합니다.

아래 방식으로 적절하게 키를 지정해줘야 정확하게 쿼리를 무효화할 수 있습니다.

키는 hierarchy 구조이기 때문에, 이를 활용해서 화면 영역을 분리하는 용도로도 키를 설정할 수 있습니다.

 

1. prefix

무효화하고 싶은 접두사로 시작하는 모든 쿼리를 무효화할 수 있습니다.

import { useQuery, useQueryClient } from '@tanstack/react-query'

const queryClient = useQueryClient()

queryClient.invalidateQueries({ queryKey: ['todos'] })

// 둘 다 'todos'로 시작하기 때문에 모두 무효화
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
  queryKey: ['todos', { page: 1 }],
  queryFn: fetchTodoList,
})

 

2. more specific query key

구체적인 특정한 쿼리키를 전달하여 그 변수가 포함된 쿼리를 무효화할 수 있습니다.

queryClient.invalidateQueries({
  queryKey: ['todos', { type: 'done' }],
})

// 무효화 O
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

// 무효화 X
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

 

3. any more variables or subkeys

exact 키워드가 의미하는 바처럼 더 이상의 변수나 하위 키가 없고, 특정 변수만 포함하는 쿼리를 무효화할 수 있습니다.

queryClient.invalidateQueries({
  queryKey: ['todos'],
  exact: true,
})

// 무효화 O
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

// 무효화 X
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

 

4. predicate function

세부적인 조건을 갖는 함수를 지정하여 true, false 값으로 무효화하고 싶은 쿼리키를 선택할 수 있습니다.

queryClient.invalidateQueries({
  predicate: (query) =>
    query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
})

// 무효화 O
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 20 }],
  queryFn: fetchTodoList,
})

// 무효화 O
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 10 }],
  queryFn: fetchTodoList,
})

// 무효화 X ( version이 10보다 작다)
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 5 }],
  queryFn: fetchTodoList,
})