React query 캐시와 캐시 상태 활용하기

boyeonJ·2023년 12월 14일
2

React

목록 보기
28/30
post-thumbnail

React Query의 캐시 상태(fresh, stale, inactive)

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이 진행됩니다.

  • 새로운 Query Instance가 마운트 될 때 (페이지 이동 후 등의 상황)
  • 브라우저 화면을 다시 focus 할 때
  • 인터넷이 재연결되었을 때
  • refetchInterval이 설정되어있을 때

Why

여기서 왜 cache에 더해 여러가지 캐시의 상태들이 필요한지에 대한 의문이 들수 있습니다.

1. UX개선

잘 정리해주신 블로그 덕분에 의문점이 해결되었습니다. 블로그의 내용을 정리하자면 stale상태를 활용한다면 cache를 다시 불러오는 그 비어있는 타임에 loading 페에지가 아닌 stale상태 데이터를 보여줌으로서 사용성을 높이는 목적을 달성할 수 있습니다. (마치 배포할때 블루, 그린과 같은 너낌!)

이미지 출처: https://www.timegambit.com/blog/digging/react-query/03

2. 네트워크 비용 감소

만약 아래와 같은 경우에 react query를 사용하지 않는다면 불필요한 네트워크 비용이 발생할 수 있습니다.

  • api에서 불러온 후 바뀌지 않는 데이터
  • post, put, delete가 발생한 경우에만 refetcing 필요
  • 변경사항을 네트워크 요청 없이 직접 수정해줄 수 있는 경우

따라서 이러한 경우 react query의 여러가지 설정을 적절히 사용해준다면 네트워크 비용을 크게 감소시킬수 있습니다.


How

1. Time 설정

📌 staleTime

fresh에서 stale로 가는 시간(api 호출을 n초 있다가 다시 해)

📌 cacheTime

inactive가 된 후 메모리에 남아있는 시간(이 시간이 지나면 가비지 컬렉터에 의해 제거됨)

2. default 설정

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>
  );
};

3. 상황별 설정

📌 api에 호출이 필요하지만 최초 호출 후 바뀌지 않는 정적 데이터

staleTime, cacheTimeInfinity로 지정

📌 post, put, delete 할때만 다시 호출이 필요한 경우

invalidateQueries() 메서드 활용
invalidateQueries 메서드는 캐싱된 쿼리를 무효화하는 메서드입니다.

어떤 상태의 데이터를 무효화 할것인지는 refetchType(active, inactive, all, none)으로 지정해줄수 있습니다. 기본값은 active입니다.

useMutation(api.commonService.postLikeData, {
  onSuccess: (data) => queryClient.invalidateQueries(['getVideoData', data.newsId]);
}

0개의 댓글