태그
목차

쿼리 키

생성일: 2024-03-16

수정일: 2024-03-16

TanStack Query의 핵심은 쿼리 키를 기반으로 쿼리 캐싱을 관리한다는 것이다. 쿼리 키는 최상위 레벨에서 배열이어야 하며, 단일 문자열이 있는 배열부터 여러 문자열과 중첩된 객체가 있는 배열과 같이 복잡할 수 있다. 쿼리 키가 직렬화 가능하고 쿼리 데이터에 대해서 고유하다면 사용할 수 있다!

간단한 쿼리 키

가장 간단한 키 형식은 상수 값이 있는 배열이다. 이 형식은 다음과 같은 경우에 유용하다:

// todos 리스트
useQuery({ queryKey: ['todos'], ... })

// 그 밖에 나머지!
useQuery({ queryKey: ['something', 'special'], ... })

변수를 포함하는 키 배열

쿼리에 데이터를 고유하게 설명하기 위해 더 많은 정보가 필요한 경우 문자열과 직렬화 가능한 객체가 포함된 배열을 사용하여 데이터를 설명할 수 있다. 이는 다음과 같은 경우에 유용하다:

// 개별 todo
useQuery({ queryKey: ['todo', 5], ... })

// "preview" 형태의 개별 todo
useQuery({ queryKey: ['todo', 5, { preview: true }], ...})

// "done" 상태의 todo 리스트
useQuery({ queryKey: ['todos', { type: 'done' }], ... })

쿼리 키는 결정론적으로 해시된다

즉, 객체의 키 순서에 관계없이 아래 쿼리는 모두 동일한 것으로 간주된다:

useQuery({ queryKey: ['todos', { status, page }], ... })
useQuery({ queryKey: ['todos', { page, status }], ...})
useQuery({ queryKey: ['todos', { page, status, other: undefined }], ... })

그러나 다음 쿼리 키는 동일하지 않다. 배열 항목 순서가 중요하다!

useQuery({ queryKey: ['todos', status, page], ... })
useQuery({ queryKey: ['todos', page, status], ...})
useQuery({ queryKey: ['todos', undefined, page, status], ...})

쿼리 함수가 변수에 의존하는 경우 쿼리 키에 변수를 포함시켜야 한다

쿼리 키는 가져오는 데이터를 고유하게 설명하므로 쿼리 함수에서 변경되는 모든 변수를 쿼리 키에 포함해야 한다. 예를 들어:

function Todos({ todoId }) {
  const result = useQuery({
    queryKey: ['todos', todoId],
    queryFn: () => fetchTodoById(todoId),
  });
}

쿼리 키는 쿼리 함수에 대한 종속성 역할을 한다는 점에 유의한다. 쿼리 키에 종속 변수를 추가하면 쿼리가 독립적으로 캐시되고 변수가 변경될 때마다 쿼리가 자동으로 다시 가져오도록 할 수 있다(staleTime 설정에 따라 다름).