React-Query 관련 블로그 Customize staleTime 글을 읽고서 더 효율적인 데이터 패칭을 구현할 수 있겠다 싶어서 React-query에서 staleTime과 cacheTime을 알아보고 사용해보고자 합니다.
React-Query 관리 개발자 Dominik은 staleTime을 이렇게 설명합니다.
쿼리가 최신 상태에서 더 이상 최신이 아닌 상태로 전환하는 시간을 나타냅니다. 쿼리가 최신 상태인 동안에는 데이터는 항상 캐시에서만 읽히며 네트워크 요청은 발생하지 않습니다! 쿼리가 최신 상태가 되지 않은 경우 (기본적값은 즉시), 여전히 데이터는 캐시에서 가져오게 되지만 일부 조건 하에서는 백그라운드 리페치가 발생할 수 있습니다.
Client-side에서 캐싱 기능이 위험한 이유에서 설명했듯이 캐싱된 데이터를 잘못 활용하게 되면 유저는 잘못된 정보를 받게됩니다. 그렇기에 staleTime이 필요합니다. Dominik 또한 cacheTime 조작이 필요한 경우가 거의 없고 필요한 것은 staleTime이라고 합니다.
staleTime은 0초가 기본값이다. 그렇기 때문에 useQuery
fetchFunc은 매번 refetch가 일어난다. cacheTime은 5분이지만 값이 stale하지 않다고 보기 때문에 refetch가 일어나는거다.
Dominik 블로그에서는 staleTime을 특정 사용 사례에 맞는 값으로 설정해야한다고 한다.
데이터가 신선한 동안에는 항상 캐시에서만 가져온다는 것입니다. 데이터가 얼마나 자주 검색하던지 간에 신선한 데이터에 대한 네트워크 요청은 표시되지 않습니다.
블로그에서 제시하는 staleTime 기본값은 20초이다. 이는 개인적인 것이고 중복 요청을 제거하기 위해 최소 20초로 설정하는 것을 좋아한다고 한다.
React Query v3부터는 QueryClient.setQueryDefaults를 통해 쿼리 키별로 기본값을 설정하는 훌륭한 방법을 지원하기 때문에 이런 방식으로 기본값 설정을 할 수 있다. 또는 특정 키값에만 지정이 가능하다.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// ✅ globally default to 20 seconds
staleTime: 1000 * 20,
},
},
})
// 🚀 everything todo-related will have a 1 minute staleTime
queryClient.setQueryDefaults(todoKeys.all, { staleTime: 1000 * 60 })
useQuery
에서 staleTime을 써봤다. Component 이동 반복 시 isfetching의 값이 5분동안 계속 false인 것을 확인할 수 있다.
const { isLoading, isFetching, isError, isSuccess, data, error, refetch } =
useQuery(["test"], getTodoFetch, {
staleTime: 1000 * 60 * 5,
}
);
기존에 캐시된 데이터가 있느냐 에 따라 isLoading
과 isFetching
이 나뉜다.
true
이다.false
이다.true
이다.React-Query 관리 개발자 Dominik은 cacheTime을 이렇게 설명합니다.
비활성 상태의 쿼리가 캐시에서 제거되는 기간입니다. 기본값은 5분입니다. 쿼리는 모든 해당 컴포넌트가 언마운트되어 관찰자가 없는 상태가 되는 즉시 비활성 상태로 전환됩니다.
기본값 5분이 지나면 Garbage Collection
에 의해 사라진다. 이를 변경하기 위해서는 cacheTime에 다른 값을 넣어주면 된다.
React-Query는 기본적으로 메모리에만 데이터를 저장하고 다른 곳에는 저장하지 않는다. 그렇기 때문에브라우저 페이지를 새로고침하면 캐시가 사라진다.
메모리에 캐싱된 데이터가 있다하더라도 stale 된 상태라면 fetching되고 새 응답으로 덮어진 캐시를 보관한다.