react query deevtool을 보면 다음과 같이 fresh, stale, fetching, inactive라는 상태가 존재합니다.
fresh(:신선한) > 데이터 그대로 사용 가능(현재 DB 저장된 데이터와 같은 데이터)
stale(:신선하지 않은) > 데이터 새로 fetching 필요(현재 DB 저장된 데이터와 다른 데이터)
inactive > 현재 컴포넌트에서 사용 x
가장 먼저 react query에서 캐시가 유효하다
라는 말은 QueryCache 객체의 queries 배열과 queriesInMap 객체에 데이터가 저장되어 있는 상태
를 의미합니다.
기본적으로 위의 3가지 상태(fresh, stale, inactive)는 모두 저장은 되어있는 데이터(캐싱 데이터)
이며, 아래 2가지의 상황에 따라 상태를 구별
한 것입니다.
1. 현재 컴포넌트 사용되는지 유무
2. refectcing이 필요한지
만약 이 캐시가 현재 DB 저장된 데이터와 같아서 그대로 사용 가능한 경우라면 api를 새로 refectcing하지 않아도 되는 fresh
상태를 의미하고, DB 데이터가 새로 업데이트 되어 refectcing이 필요한 stale
상태라고 합니다.
따라서 stale일 경우에 refectcing이 되는데요. 여기서 무조건 stale라고 해서 실시간으로 api가 refectcing 되는 것이 아니라 아래와 같은 상황일 경우 refectcing이 진행됩니다.
여기서 왜 cache에 더해 여러가지 캐시의 상태들이 필요한지에 대한 의문이 들수 있습니다.
잘 정리해주신 블로그 덕분에 의문점이 해결되었습니다. 블로그의 내용을 정리하자면 stale상태를 활용한다면 cache를 다시 불러오는 그 비어있는 타임
에 loading 페에지가 아닌 stale상태 데이터를 보여줌으로서 사용성을 높이는 목적을 달성할 수 있습니다. (마치 배포할때 블루, 그린과 같은 너낌!)
이미지 출처: https://www.timegambit.com/blog/digging/react-query/03
만약 아래와 같은 경우에 react query를 사용하지 않는다면 불필요한 네트워크 비용이 발생할 수 있습니다.
따라서 이러한 경우 react query의 여러가지 설정을 적절히 사용해준다면 네트워크 비용을 크게 감소시킬수 있습니다.
fresh에서 stale로 가는 시간(api 호출을 n초 있다가 다시 해)
inactive가 된 후 메모리에 남아있는 시간(이 시간이 지나면 가비지 컬렉터에 의해 제거됨)
QueryClient의 defaultOptions에 staleTime과 cacheTime 지정해줄수 있습니다.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60,
cacheTime: 1000 * 60 * 5,
}
},
});
const App = ({ Component, pageProps }: AppProps) => {
return (
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
</QueryClientProvider>
);
};
staleTime
, cacheTime
을 Infinity
로 지정
invalidateQueries() 메서드 활용
invalidateQueries 메서드는 캐싱된 쿼리를 무효화하는 메서드입니다.
어떤 상태의 데이터를 무효화 할것인지는 refetchType(active, inactive, all, none)으로 지정해줄수 있습니다. 기본값은 active입니다.
useMutation(api.commonService.postLikeData, {
onSuccess: (data) => queryClient.invalidateQueries(['getVideoData', data.newsId]);
}