react-query의 장점 중 하나인 캐싱 기능을 어떻게 구현할 수 있을까?
react-query를 공부하기 시작한지 얼마 안 되었는데, 내가 react-query로 관심을 두게 된 이유 중 하나이다. 캐시는 자주 사용하는 데이터나 값을 미리 복사하여 저장하여 서비스 할 수 있게 하는 임시 저장소이다.
구현하는 방법을 알아보자.
우선 react-query에서 캐싱 사용법에 대해서 이해하려면 staleTime과 cacheTime에 대한 이해가 필요하다.
이 두 가지는 QueryClient에서 defaultOptions에서 전역 설정도 가능하지만, 지금은 useQuery에서 어떻게 사용하는지만 살펴보자.
const { data: userInfo } = useQuery(
['user'],
fetchUser,
{
staleTime: 60 * 1000, // 1분, default >> 0
cacheTime: 60 * 5 * 1000 // 5분, default >> 5분
}
)
위와 같이 useQuery의 세 번째 인자로 option을 넘길 수 있는데, 여기서 staleTime과 cacheTime을 설정할 수 있다.
staleTime 만큼 시간이 지나면 데이터는 stale 상태로 변경된다.
staleTime의 default값은 0이다. 따라서 따로 설정해주지 않는다면 useQuery로 받아온 데이터는 받아오자마자 곧바로 stale한 상태로 변하는 것을 devtools를 통해서 확인할 수 있을 것이다.
inactive 상태인 캐시 데이터가 메모리에 남아있는 시간
cacheTime 이후에는 가비지 컬렉터에 의해 메모리에서 삭제된다.
default 값은 5분이다.
useQuery를 호출할 때 staleTime이 설정되어 있지 않다면 캐싱을 사용할 수 없다. 이유는 아래와 같다.
staleTime이 0이라면 캐싱 되어 있는 데이터는 항상 stale하기 때문에 refetching을 하게 되어서 서버에 계속 요청을 하게 된다.
그리고 staleTime보다 cacheTime이 더 짧다면 데이터가 상하지 않았지만 캐시에 있는 데이터는 이미 GC에 의해 처리 되었으므로 캐싱 기능을 사용할 수 없다.
refetch는 캐싱 결과는 조회하지 않고 완전히 무시한 채로 그냥 서버에 요청을 날린다.
refetch는 지금 가지고 있는 데이터가 fresh하지 않고 stale하기 때문에 새 데이터로 갱신해야 하기 때문에 사용된다.
refetching의 전제 조건은 데이터가 stale 상태여야 된다는 것이다.
query key에 react state를 포함시키고, state가 변경되면 refetch
refetchOnWindowFocus >> 데이터가 stale 상태일 경우 윈도우에 포커즈가 이동될 때 마다 refetch
refetchOnMount >> 마운트 될 때마다 refetch
refetchOnReconnect >> 연결이 끊어졌다가 재 연결 되었을 때 refetch
clientQuery.invalidateQueries() >> 고의로 쿼리 무효화를 했을 때 refetch, 서버 데이터를 변경한 후 새로운 데이터를 받아오기 위해 고의로 쿼리를 무효화 >> 데이터가 바로 stale 상태로 변경됨과 동시에 refetch 실행
명시적으로 refetch 함수를 호출 할 때