useQuery refetch 옵션, 캐시 상태와 refetchInterval

김민아·2023년 1월 12일
1

useQuery refetch 관련 옵션

useQuery에서 query의 고유한 query key와 promise를 리턴하는 queryFn가 필요하다. useQuery의 세번째 인자인 옵션 중 캐시 상태, refetch 조건과 관련있는 옵션에 대해서 알아보았다.

📌 staleTime

staleTime: number | Infinity

(위 이미지 - 기본 / 아래 이미지 - 커스텀 5000ms)

클라이언트로 불러온 서버의 데이터가 얼마나 오래되었는지(stale) 정도를 의미한다. 즉, fresh 상태를 얼마나 유지할지로 볼 수 있다. 기본값은 0으로 즉시 fresh에서 stale되는 것을 확인할 수 있다.

number 혹은 I

코드

const { isLoading, isError, data } = useQuery<IHistorical[]>(
  ["ohlcv", coinId],
  () => fetchCoinHistory(coinId),
  {
    staleTime: 5000,
  },
);

stale 캐시의 refetch 조건

stale 상태인 쿼리가 백그라운드 refetch 되는 조건은 👉 이전 블로깅할 때 확인해 본 적이 있다.

+) 테스트를 하다보면 더 자주 refetch 되는 것 같은데, refetchOnWindowFocus 외에도 DevTools과 app간의 포커싱 이동에도 refetch를 진행하기 때문이라고 한다.


📌 cacheTime

cacheTime: number | Infinity

(위 이미지 - 기본 / 아래 이미지 - 커스텀 5000ms)

cacheTime을 변경하기 위해서 useQuery 세번째 인자에 옵션을 추가한다. "inactive" 쿼리는 cacheTime 이후에는 가비지 컬렉터에 의해 삭제된다.

코드

const { isLoading, isError, data } = useQuery<IHistorical[]>(
  ["ohlcv", coinId],
  () => fetchCoinHistory(coinId),
  {
    cacheTime: 5000,
  },
);

📌 refetchInterval

refetchInterval: number | false | ((data: TData | undefined, query: Query) => number | false)

백그라운드 refetch 외에 주기적으로 서버의 데이터를 동기화할 필요가 있을 때 refetchInterval를 사용할 수 있다. 지금 듣고 있는 강의의 예제인 coin tracker 앱도 코인 가격을 실시간으로 반영하기 위해 5초마다 refetch를 시도한다.

✅ staleTime, cacheTime과 차이점은

staleTime, cacheTime은 캐시의 상태를 유지하는 시간을 의미한다. refetch가 되는 조건(Mount 혹은 windowFocus)에 기준이 되거나 가비지 수집의 기준이 된다.

반면, refetchInterval는 일정시간을 기준으로 refetch한다. 다만 브라우저가 포커싱되어야 하며, 포커싱하지 않아도 백그라운드에서 refetch하는 refetchIntervalInBackground 옵션이 있다.
물론 둘 다 default는 false이다.

코드

const { isLoading: priceLoading, data: priceData } = useQuery<ICoinPrice>(
    ["price", coinId],
    () => fetchCoinPrice(coinId),
    {
      refetchInterval: 5000,
      refetchIntervalInBackground: true,
    },
  );

📌 refetchOnMount

refetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")

컴포넌트를 마운트할 때, 캐시가 남아있는 경우 캐시를 사용하여 빠르게 로드된다. 이때 refetch를 시도할지에 대한 옵션이다. default는 true이며, false, "always" 값으로 지정할 수 있다.
중요한 것은 마운트된 시점에 캐시 상태(stale)이다.

  • true일 때: 캐시가 stale 상태이면 refetch한다.
  • false일 때: 캐시의 상태가 어떻든 refetch를 하지 않는다.
  • "always"일 때: 캐시의 상태가 어떻든 refetch를 한다.

📌 refetchOnWindowFocus

refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")

사용자가 앱(윈드우)를 벗어났다가 다시 돌아올 경우, 기본적으로 백그라운드에서 refetch를 실행한다. (default가 true) refetchOnWindowFocus 옵션에서 false로 설정할 수 있다.

코드

const { isLoading: priceLoading, data: priceData } = useQuery<ICoinPrice>(
    ["price", coinId],
    () => fetchCoinPrice(coinId),
    {
      refetchOnWindowFocus: false,
    },
  );

더 공부해 볼 것

  • per-query 설정을 알아보았으니, queryClient로 global 설정하기 알아보자.
  • focusManager로 focus 이벤트를 핸들링할 수 있는 것 같다.

출처

0개의 댓글