React

[리액트] Tanstack-Query staleTime과 cacheTime

ejunyang 2024. 7. 4. 15:07

 

포켓몬 도감 웹 페이지를 리액트 쿼리로 서버 상태 관리를 했다. 그 중 헷갈리는 개념인 staleTime과 cacheTime을 내가 이해한대로 정리해보려고 한다. 

 


 

devtools

우선, 리액트 쿼리를 사용할 때 쿼리의 상태를 확인하기 위해 devtool을 먼저 설치하고 시작!!

yarn add @tanstack/react-query-devtools
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import React from "react";

const QueryProvider = ({ children }: React.PropsWithChildren) => {
  const queryClient = new QueryClient();
  return (
    <QueryClientProvider client={queryClient}>
      <ReactQueryDevtools initialIsOpen={false} /> //이 코드 추가!!
      {children}
    </QueryClientProvider>
  );
};

export default QueryProvider;

 

 

staleTime

staleTime은 언제까지 신선한 데이터를 유지할지 기간을 지정한다. 데이터 상태가 stale 이라면 이전 데이터는 캐싱되어있지만, 업데이트는 되지 않은 상태이다.(데이터를 새로 패칭해야 하는 상태) stale 단어 그대로 "탁한", "신선하지 않은" 상태이다.

 

staleTime은 기본적으로 0 으로 default value로 세팅 되어있다.

staleTime > 0으로 설정되면, staleTime 이후에도 이전 캐시 결과를 사용할 수 있다.

staleTime === 0으로 설정되면, 데이터가 한 번 "stale" 상태가 되면 다시 쿼리를 수행하여 업데이트된 데이터를 가져오고 받아오는 즉시 stale하다고 판단해서 캐싱 데이터와는 무관하게 계속 fetching을 수행한다.

데이터가 fresh한 상태일 때는 페이지를 이동했다가 돌아와도 다시 패치되지 않는다. 왜냐하면 이미 신선한 상태의 데이터를 다시 패치해서 업데이트해줄 필요가 없기때문!!

 

global 설정 변경

React Query v3부터는 QueryClient.setQueryDefaults를 통해 쿼리 키별로 기본값을 설정할 수 있다. 

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5000,
    },
  },
});

 

useQuery별 설정 변경

const { isPending ,isFetching, data: pokemon } = useQuery({
  queryKey: ["pokemon"],
  queryFn: () => fetchPokemonData(),
  staleTime: 5000,
});

 

아래 화면처럼 쿼리 상태를 확인 할 수 있다. 나는 5초동안 신선한 데이터를 유지하도록 설정(staleTime: 5000) 했기 때문에 5초 뒤 frech -> stale로 상태가 변경되는 것을 확인할 수 있다.

 

 

 

cacheTime(gcTime)

사용하지 않는 캐시 데이터를 언제까지 가지고 있을껀지 설정하는 옵션이다.

cacheTime은 기본적으로 5분(1000*60*5)으로 default value로 세팅 되어있다.

컴포넌트가 언마운트되거나 쿼리가 더 이상 필요하지 않을 때를 inactive 상태로 변경되며 캐시는 cacheTime 만큼 유지된다.

 

global 설정 변경

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      gcTime: 2000,
    },
  },
});

 

useQuery별 설정 변경

const { isPending ,isFetching, data: pokemon } = useQuery({
  queryKey: ["pokemon"],
  queryFn: () => fetchPokemonData(),
  gcTime: 5000,
});

 

 

 

 

프로젝트 적용

진행하고 있는 포켓몬 도감에서는 포켓몬 데이터가 변하는 값이 아니기 때문에 staleTime을 infinity로 설정해주었다. 그럼 계속해서 신선한 데이터를 가지고 있어서 페이지 이동을 해도 데이터를 리패칭하지 않는다.

  const {
    data: pokemonData,
    error,
    isPending,
    isFetching,
  } = useQuery<Pokemon[]>({
    queryKey: ["pokemonData"],
    queryFn: () => fetchPokemonData(),
    staleTime: Infinity,
  });