프로젝트를 진행하면서 별도의 설정을 하지 않았기 때문에 staleTime
은 0, gcTime
은 5분으로 설정되어 있다. 즉, 데이터가 바로 오래된(stale) 상태로 된다는 뜻인데... 이걸 다루면 사용자 경험 향상에 좀 더 도움이 되지 않을까? 싶어서 설정하며 간단하게 정리했다. 그리고 다루다 보니 계속 헷갈려서 정리해두는 편이 다음을 위해서도 더 좋다고 생각했다.
일단 공식문서에서 기본적으로 기억하라고 하는 부분은 다음과 같다.
useQuery
나 useInfiniteQuery
를 사용한 쿼리 인스턴스는 기본적으로 데이터를 낡은(stale)것으로 여김staleTime
옵션을 사용해서 설정해라. staleTime
이 길수록 쿼리가 데이터를 자주 리프레시 하지 않는다.여기서 잘 봤어야 하는데... staleTime
은 데이터를 몇분 동안 낡았다고 취급할까요? 가 아닌 몇 분 뒤에 이 데이터를 낡았다고 할까요? 임... 즉, staleTime
동안 이 데이터는 신선함. 그리고 데이터가 신선하면 백그라운드에서 refetch 되지 않음.
데이터가 캐시되므로, 신선한 데이터는 여러 페이지 혹은 컴포넌트에서 공유됨. 즉, 빈번한 업데이트가 필요하지 않은 데이터라면 staleTime
을 길게 가져갔을 때 불필요한 네트워크 요청을 줄일 수 있다.
낡은 데이터의 리페치 조건은 다음과 같다.
refetchInterval
를 설정할경우 지속적인 자동 페칭이 발생한다.버전 5에서 이름이 변경되었다(참고).
데이터가 사용되지 않고 있을 때(컴포넌트의 언마운트, 데이터가 inactive 상태인 경우) 가비지 콜렉션을 통해 캐시에서 제거되는 시간. 이 시간이 지나면 캐시에서 제거됨. 즉, inactive한 데이터가 캐시에 살아있을 수 있는 기간이라 보면됨. gcTime
은 기본적으로 5분이고, 역시나 gcTime
설정으로 바꿀 수 있음.
staleTime
동안 신선하게 유지됨.2.staleTime
이내 (신선한 상태)
gcTime
은 영향x. 데이터가 사용중이기 때문.staleTime
만료. (10초 지남)gcTime
에는 영향 x.gcTime
의 카운트다운이 시작됨(4분 59초.. 4분 58초...). 그렇게 0까지 카운트다운되면 데이터가 캐시에서 제거됨. staleTime
과 gcTime
은 다시 10초, 5분으로 설정됨.
회원의 전화번호를 가져오는 페이지에서 직접 적용해보았다. 회원정보는 실시간성이 딱히 중요하지도 않고(전화번호가 실시간으로 바뀌는것도 아니니), 회원 본인이 이 정보를 수정한 경우에만 업데이트 되면 된다(현재 이를 위해 업데이트 후 invalidateQueries
를 호출한다).
현재는 전역으로 staleTime
이 0으로 설정되어 있다. 즉, 데이터가 페치된 직후 바로 "낡았다"라고 판단됨. 따라서 컴포넌트가 언마운트 되었다가 다시 마운트되는 경우(다른 페이지로 갔다가 다시 회원 정보 페이지로 오는 경우 등)에 refetch가 발생하는데, 그 사이에 회원정보가 변하지 않으니 불필요한 refetch라고 할 수 있다.
이런 데이터는 실시간성이 중요하지 않고, 한 번 fetch된 이후로는 변경되기 전까지 그대로 사용해도 상관없는 데이터라고 판단해 staleTime
이 길어도 상관없다고 생각했다. 그렇기에 staleTime
를 Infinity
로 설정했다.
export default function useGetMemberInfo() {
const { data } = useSuspenseQuery<{ phoneNumber: string }, AxiosError>({
queryKey: ["memberInfo"],
queryFn: () => axiosInstance.get(`/members/me`).then((res) => res.data),
staleTime: Infinity,
});
return { data };
}
해당 설정을 통해 회원 전화번호는 항상 "신선한" 상태이고, 사용자가 변경하지 않는 이상 refetch되지 않는다. 단, 불필요한 데이터 공간 차지를 막기 위해 gcTime
은 아직 5분 이므로, 페이지를 벗어나고 5분 후 다시 들어올 경우엔 전화번호를 다시 fetch 해야한다.
모호하게만 알고 있던 staleTime
과 gcTime
에 대해 본격적으로 알아보며 사용자 경험을 위한 설정까지 생각해볼 수 있었다. 예시에서는 회원 정보에만 적용했지만 다른 부분에도 적용하면서 사용자 경험을 더욱 향상시킬 수 있지 않을까 기대되었고, 이러한 부분을 개발자가 편하게 설정할 수 있도록 한 점이 Tanstack Query의 많은 장점 중 하나가 아닐까 생각된다.