쿼리 키(Query Key)는 TanStack Query가 캐시 항목을 식별하고 무효화 범위를 고르는 배열이다. 키를 일반적인 것에서 구체적인 것 순서로 쌓고, 한 곳(키 팩토리)에서 만들게 하면 부분 일치(Partial Matching)로 원하는 범위만 정확히 무효화할 수 있다.
const todoKeys = {
all: ['todos'] as const,
lists: () => [...todoKeys.all, 'list'] as const,
list: (filters: string) => [...todoKeys.lists(), { filters }] as const,
details: () => [...todoKeys.all, 'detail'] as const,
detail: (id: number) => [...todoKeys.details(), id] as const,
}
queryClient.removeQueries({ queryKey: todoKeys.all }) // todo 관련 전부
queryClient.invalidateQueries({ queryKey: todoKeys.lists() }) // 목록만- 키는 앞에서부터 부분 일치로 매칭된다. 그래서
['todos', 'list', …]구조면['todos', 'list']로 모든 목록을 한 번에 고를 수 있다 - 키 문자열을 여기저기 손으로 쓰면 오타 하나로 무효화가 안 된다. 팩토리는 이 실수를 막는다(매직 넘버와 설명 상수, DRY 원칙)
- queryFn의 인자는 키에서 꺼낸다.
queryFn은{ queryKey }를 받으니 인라인 함수로 값을 다시 넘기지 말고 키에서 읽는다. 키에 넣지 않은 값을 함수가 쓰면 캐시가 섞인다(eslint-plugin-query가 잡아 준다)
const fetchTodos = ({ queryKey: [{ state, sorting }] }) => api.get(`todos/${state}?sort=${sorting}`)
useQuery({ queryKey: [{ scope: 'todos', entity: 'list', state, sorting }], queryFn: fetchTodos })
queryClient.invalidateQueries({ queryKey: [{ entity: 'list' }] }) // 모든 scope의 목록- 키 요소를 객체 하나로 만들면 이름으로 꺼낼 수 있고, 객체 부분 일치로 "모든 목록" 같은 범위도 고를 수 있다
전체 개념은 TanStack Query.
출처: TkDodo - Effective React Query Keys: Use Query Key factories · Leveraging the Query Function Context: Object Query Keys