❗ Query Key
기본적으로 리액트 쿼리는 쿼리의 고유한 key를 바탕으로 해당 쿼리에 대한 캐싱을 관리한다.
쿼리 키는 단순히 문자열을 포함하는 배열에서부터, 중첩 객체를 가지는 배열이 될 수도 있다.
쿼리 키가 고유하고, 직렬화를 가능한 한 사용할 수 있다.
✔ 단순한 Query key
주로 리스트나, 인덱스 리소스, 위계가 없는 리소스에 대해서는 쿼리 키를 작성한다.
const { data: appointments = fallback } = useQuery(
[queryKeys.appointments],
() => getAppointments(monthYear.year, monthYear.month)
);
하지만 단순한 쿼리키의 문제점이 있다.
바로 문제점에 대해 쉽게 이해할 수 있도록 예시를 통해 살펴보자
이러한 달력이 있고 예약 사항을 React Query를 통해 관리한다고 가정해보자.
예약 정보는 appointments라는 쿼리키를 통해 데이터를 가져오고 있다.
여기서 발생하는 문제는 뭘까 ?
문제는 바로 동일한 Query key를 가지고있다보니
다음 월로 이동했을때도 이전에 있던 데이터가 동일하게 다음 월으로 불러와버린다.
왜 이러한 문제가 발생하냐면 모든 쿼리에 동일한 Query key를 사용해버리기 때문이다.
그렇기 때문에 이전 달이나 다음 달 버튼을 클릭 했을 때 쿼리 데이터는 만료(stale) 상태지만 리페치(refetch)를 트리거 할 대상이 없다. 그렇기 때문에 이러한 상황 같은 경우 매 월에 고유한 Query key를 갖게하면 해결이 된다.
Query key는 항상 의존성 배열로 취급하게하여 데이터가 변경될 경우 키도 변경되어 각 데이터에는 고유한 쿼리키를 갖도록 해야한다.
이해했다면 발생한 문제를 해결해보자.
✔ 고유한 값을 갖는 Query key
const { data: appointments = fallback } = useQuery(
[queryKeys.appointments, monthYear.year, monthYear.month],
() => getAppointments(monthYear.year, monthYear.month)
);
일단 앞서 설명한 부분에 따르면 Query key는 이러한 형태로 만들어지는게 옳은 형태라고 볼 수 있다.
추가적으로 알아두면 좋을 부분이 배열의 첫 번째 항목에는 데이터 무효화를 하기위해 모든 배열의 공통점이 되는 공통 접두사로 해두는게 좋다. 그러면 나중에 한 번에 무효화를 할 수 있기 때문이다.
** 해당 useQuery에서는 queryKeys의 상수를 다른 파일에서 가져왔는데 queryKeys.appointments에는 "appointments"라는 문자열이 들어있다. 이렇게 문자열을 상수로 관리하는 이유는 오타같은 사소한 문제로 인해 발생하는 상황을 예방하기 위해서다.
이렇게 각 데이터별 고유한 Query Key를 지정했다면
해당 사진처럼 올바르게 동작하는걸 보게될 수 있을것이다.
아래 ReactQueryDevtools를 보면 각 Query key가 배열의 공통점이 되는 공통 접두사로 이루어져 있고 두 번째와 세 번째 항목은 각 Query key의 고유한 항목이 되는 년도와 월으로 이루어져 있는것을 확인할 수 있을 것이다.
파이팅 ㅎ
'자바스크립트 - React.js' 카테고리의 다른 글
[ReactQuery] refetch에 대해서 알아보자 ! (feat. 전역 refetching, Polling) (0) | 2023.07.24 |
---|---|
[ReactQuery] useQuery의 select 옵션을 사용해보자 ! (0) | 2023.07.18 |
[ReactQuery] 데이터를 미리 가져와 캐시에 넣는 Prefetching ! (0) | 2023.07.10 |
[ReactQuery] QueryClient의 defaultOptions를 사용한 전역 에러 핸들링 (0) | 2023.07.06 |
[React.js] <React.Fragment>에 대해서 알아보자 (0) | 2023.07.01 |