쿼리 키는 각 쿼리를 식별하는 역할을 하며 캐싱, 데이터 동기화, 리페칭에 사용된다.
배열 또는 문자열로 정의하며, 같은 키를 가진 쿼리는 같은 데이터로 인식된다.
아래의 쿼리는 다른 키를 가지고 있어 따로 관리된다.
useQuery({ queryKey: ['todos'], queryFn: fetchTodos })
useQuery({ queryKey: ['todos', userId], queryFn: fetchUserTodos })
쿼리 키는 배열로 작성하는 것이 권장된다.
이유는 계층적 구조를 가져 더 세밀한 관리가 가능하다. 또 검색 및 필터링에 유리하다.
useQuery({ queryKey: ['todos', {userId: 1}], queryFn: fetchUserTodos })
queryKey: ['todos', {userId: 1}]
를 사용하면 특정 사용자만 조회하는 쿼리로 관리가 가능하다.
쿼리 키에 객체도 포함이 가능하다. 하지만 마지막 요소로 두는 것이 좋다.
이유는 배열의 앞부분을 기준으로 더 쉽게 필터링이 가능하기 때문이다.
useQuery({ queryKey: ['todos', { userId: 1, status: 'done' }] })
위처럼 하면 [’todos’] 쿼리와 구분이 가능하면서, queryClient.invalidateQueries({ queryKey: ['todos'] })
로 모든 todos 쿼리를 한 번에 무효화할 수 있다.
쿼리 키에 필터링 정보를 넣어 필터링이 변경될 때마다 새 데이터를 가져오게 할 수 있다.
useQuery({ queryKey: ['todos', { userId, status }], queryFn: fetchTodos })
// ['todos', { userId:1, status:done }] ≠ ['todos', { userId:1, status:pending }]
status가 done이면 완료된 할 일, pending이면 진행중인 할 일을 가져온다. 상태가 다르면 다른 키로 구분되어 각가 캐시된다.
키 순서가 달라도 동일한 쿼리로 인식된다.
useQuery({ queryKey: ['todos', { status, page }] })
useQuery({ queryKey: ['todos', { page, status }] })
useQuery({ queryKey: ['todos', { page, status, other: undefined }] })
하지만 객체 내부의 값이 다르면 별개의 쿼리로 취급된다.
useQuery({ queryKey: ['todos', { page: 1 }] })
useQuery({ queryKey: ['todos', { page: 2 }] })
// Todo 목록 조회
useQuery({ queryKey: ['todos'], queryFn: fetchTodos })
// 특정 사용자 Todo 조회
useQuery({ queryKey: ['todos', { userId }], queryFn: fetchUserTodos })
// 특정 필터 적용된 Todo 조회
useQuery({ queryKey: ['todos', { userId, status: 'done' }], queryFn: fetchUserTodos })
// 모든 Todo 캐시 무효화
queryClient.invalidateQueries({ queryKey: ['todos'] })
// 특정 유저의 Todo 캐시 무효화
queryClient.invalidateQueries({ queryKey: ['todos', { userId }] })
두 방식은 모두 특정 데이터를 조회할 때 사용하는 패턴이지만, 목적과 사용 범위가 다르다.
이 패턴은 특정 단일 항목을 조회할 때 사용한다. 보통 GET /todos/1 같은 요청에 해당한다.
예를 들면 특정 할 일의 상세정보, 특정 게시글 조회 등이 있다.
이 패턴은 여러 데이터를 조회할 때 사용한다. 보통 GET /todos?userId=1 같은 요청에 해당한다.
예를 들면 특정 사용자의 모든 할 일 목록, 특정 카테고리의 게시글 목록 등이 있다.
정리하면 ['todos', id]는 단일 리소스 조회, ['todos', { 필터 }]는 조건부 목록 조회에 활용된다.