캐시란?
데이터를 미리 복사해 놓는 임시 장소를 말하는데요.
보통 저장 공간의 크기는 작지만, 데이터를 가져오는 속도는 아주 빠르다는 특징이 있습니다. 따라서 자주 사용하는 데이터를 캐시에 저장해 두면, 해당 데이터를 훨씬 빠르게 가져와서 사용할 수 있습니다.
웹 브라우저는 기본적으로 캐시를 사용해서 속도를 높이고 네트워크 비용을 아끼는데요. 사이트에 접속했을 때 받아 온 데이터를 캐시 형태로 저장해서, 사용자가 같은 사이트에 접속하면 서버에 매번 데이터를 다시 요청하는 게 아니라 저장해 놓은 데이터를 유저에게 보여줍니다. 그리고 이렇게 캐시를 사용하는 걸 '캐싱'이라고 합니다.
리액트 쿼리는 백엔드에서 이제 막 데이터를 받아와 캐시에 저장된 데이터는 fresh, 즉 신선한 상태로 판단합니다. 그러다가 stale time이라고 불리는 특정 시간이 지나면 데이터는 stale, 즉 신선하지 않은 상태가 됩니다. 마지막으로 컴포넌트가 언마운트되면(DOM 트리에서 제거되면) 해당 데이터가 쓰이지 않는 상태가 되어서 데이터는 inactive 상태가 됩니다.

먼저 useQuery()가 실행되는 컴포넌트가 마운트되면 useQuery()를 통해 쿼리 함수가 실행되고 데이터를 받아옵니다.
받아 온 데이터는 useQuery()에서 지정해 줬던 쿼리 키를 이용해 캐싱, 즉 캐시에 저장이 되는데요. 이렇게 캐시에 저장된 데이터는 fresh 상태에서 staleTime이 지나면 stale 상태로 변경됩니다.
유저가 데이터를 요청하게 되면 캐시된 데이터를 먼저 보여주게 되는데, 이때 데이터가 fresh 상태면 추가적인 refetch를 진행하지 않고, stale 상태면 백그라운드에서(자체적으로 알아서) refetch를 진행합니다.
refetch가 끝나면 새로운 데이터로 유저에게 보여주고요.
컴포넌트가 언마운트되어서 데이터가 inactive 상태가 되면 gcTime(가비지 컬렉션 타임) 동안 캐시에 저장되어 있다가 그 이후에 가비지 콜렉터에 의해 삭제가 되면서 이 여정은 마무리 됩니다.
리액트 쿼리에서는 기본적으로 staleTime은 0, gcTime은 5분인데요. staleTime이 0이므로 기본적으로는 매번 서버에서 데이터를 다시 받아오게 됩니다. 그래서 별도의 옵션 값 조정 없이 받아 온 데이터를 리액트 쿼리 개발자 도구로 살펴보면 처음 데이터를 받아 오자마자 데이터가 stale 상태가 되는 것을 알 수 있는데요.
이를 변경하려면 useQuery()에서 staleTime 옵션값을 변경해 주면 됩니다.
아래 코드와 같이 staleTime 값을 1분으로 변경하면 처음 데이터를 받아 와도 1분간은 fresh 상태로 유지되는 것을 확인할 수 있습니다. 그러다가 1분이 지나면 stale한 상태로 변하게 되고요. 마찬가지로 가비지 컬렉션 타임은 gcTime 옵션 값을 활용해서 변경할 수 있습니다.
function HomePage() {
const result = useQuery({
queryKey: ['posts'],
queryFn: getPosts,
staleTime: 60 * 1000,
gcTime: 60 * 1000 * 10,
});
console.log(result);
return <div>홈페이지</div>;
}
참고로 staleTime과 gcTime은 밀리초(ms)가 기준이기 때문에, 1000이 곧 1초를 의미합니다. 1분은 60초이니 60을 곱해 주었고요. 여기서 gcTime은 10을 추가로 곱해서 10분으로 설정해 보았습니다.