캐싱에 대해서 먼저 얘기하기 전에 캐시에 대해서 먼저 알아야한다.
cache는 데이터를 저장하는 저장공간을 의미한다. 저장할 수 있는 데이터의 양은 작지만 불러오는 속도가 빠르다는 이점이 있다. 그래서 브라우저에서는 모든 데이터를 실시간으로 받아서 적용하는 것이 아니라 캐시에 저장해둔 정보를 사용한다.
그리고 이런 캐시를 사용하는 것을 캐싱이라고 한다.
그럼 리액트 쿼리에서 캐싱은 어떻게 사용되고 있을까? useQuery를 사용하면서 queryKey값을 지정했었다. 그리고 지정한 key값에 따라 캐시에 데이터를 저장한다.

그러면 이 캐시에 저장된 데이터를 가져와서 사용하고 리액트 쿼리가 알아서 refetch를 해주는 것이다. 그렇다면 어떤 기준으로 지정된 데이터를 사용하고 refetch를 진행할까.
백엔드를 통해 받아온 데이터는 캐시에 저장되고 저장된 데이터는 상태를 구분한다.

이 위에 있는 것들이 캐시 데이터 상태이다. 맨처음 데이터를 요청하고 캐시에 저장된 데이터는 fresh상태이다. 그리고 일정 시간이 지나면 stale상태로 전환된다. 그리고 해당 컴포넌트가 언마운트되면 inactive상태가 된다. 이런 상태에 따라 refetch를 실행한다.
컴포넌트에서 queryKey가 같은 데이터를 요청했다고 가정해보자. 만약 캐시에 저장된 데이터가 fresh상태인 경우에는 신선한, 최신화된 데이터이기 때문에 백엔드에서 다시 데이터를 받아오지 않는다. 그리고 요청한 데이터는 캐시에 저장된 데이터를 사용한다. 하지만 일정한 시간이 지난후에 stale상태, 탁한 상태가 되면 다시 받아올 상태라고 인식해 다시 백엔드에서 데이터를 받아온다.
간단한 코드를 작성해서 확인해보자.

지금 포스트 데이터를 받아온 상태이고 해당 데이터는 fresh상태이다. 그리고 이 상태에서 아무리 데이터를 요청해도 다시 백엔드로 리퀘스트를 보내지 않고 캐시에 저장된 데이터를 사용한다.

반면에 stale상태라면 매번 요청을 보낼때마다 백엔드에 데이터를 요청한다.
이제 stale time을 조절해보겠다.
const {
data: postsData,
isError,
isPending,
} = useQuery({
queryKey: postsQueryKey,
queryFn: postsQueryFn,
staleTime: 60 * 1000,
});
useQuery의 옵션으로 staleTime을 넣어주면 된다. 밀리세컨을 사용하기 때문에 위의 시간은 1분이다. 1분동안 fresh상태가 유지되고 1분 이후에는 stale상태로 변환된다. 이 값을 설정하지 않으면 기본적으로 0이 적용된다. 그러면 매번 새로운 데이터를 받도록 하는것인데 내가 구현할 기능에 따라 시간을 적용시켜주면 된다.
그러면 캐시에 저장된 값은 계속 남아있는걸까? 아니다. 이것또한 내가 컨트롤이 가능하다. Garbage Collection Time이라고 gcTime을 옵션으로 지정해주면 된다.
컴포넌트가 언마운트되서 사용하지 않는 데이터는 inactive 상태가 되는데 5분이 기본적으로 설정된다. inactive상태로 캐시에 남아있다가 gcTime이 초과되면 캐시에서 삭제된다.
const {
data: postsData,
isError,
isPending,
} = useQuery({
queryKey: postsQueryKey,
queryFn: postsQueryFn,
staleTime: 60 * 1000,
gcTime: 60 * 1000 * 10,
});
이렇게 gcTime을 지정해주면 10분으로 설정된다.
아직 제대로 사용하고 활용하지 못한 부분이라 조금 아쉽다. 이론 공부만 한 느낌이랄까... 빨리 프로젝트에 적용시켜보고 싶다. 간단한 데이터만 리액트 쿼리를 적용해보면 좋을 것 같다. 리액트 쿼리를 좀더 공부해봐야겠다.