React Query 캐싱을 제대로 활용하자

김지원·2023년 3월 21일
4

Frontend

목록 보기
19/28

React Query

✨ react query 캐싱

react query는 아무 옵션을 설정하면 않으면 ❗️ 캐싱되지 않는다. ❗️

❓why❓

staleTimecacheTime의 기본값이 각각 0분5분 이다.

따라서 데이터는 캐싱 되지만, staleTime 이 0분 이므로
항상 caching 되어 있는 데이터를 stale 하다고 여기기 때문이다.
즉, 캐싱 데이터를 전혀 사용하지 못하는 상태라고 보면 된다.

⏳ staleTime

🔵 default 값: 0분

🔴 staleTime이란?

데이터가 freshstale 상태로 변경되는데 걸리는 시간
- ex) staleTime이 3000이면 fresh 상태는 3초 뒤에 stale 상태로 변경됨

  • fresh 상태일 때는 query instance가 새롭게 mount 되어도 fetch(네트워크 요청)가 일어나지 않는다.
  • 데이터가 fetch 되고 나서 staleTime이 지나지 않았다면 fresh 상태임을 의미하고, 따라서 unmount 후 다시 mount 되어도 fetch가 일어나지 않는다.
  • react query는 기본적으로 ✅ caching 된 datastale한 상태로 여긴다.
    • staleTime 의 기본값이 0 이기 때문에 일반적으로 fetch 후에 바로 stale이 된다.

🗒️ 용어 설명

  • stale: 용어 그대로 썩은 이라는 의미다. 즉, 최신 상태가 아님을 의미
  • fresh: 용어 그대로 신선한 이라는 의미다. 즉, 최신 상태를 의미

🧐 staleTime에 대한 자세한 설명

fetch로 전달받은 데이터는 react query의 자료구조 내용 중 cache에 저장이 된다.

이 때, 이 캐시 데이터의 fresh 상태가 stale 상태로 변경되는데 걸리는 시간이 staleTime 이다.

default 값이 0 이므로, 데이터를 fetch하는 즉시 stale 이라고 판단하여 캐싱 데이터와는 무관하게 계속해서 fetching을 수행한다.

🧐 stale 상태일 때 어떤 경우에 refetch 되는가?

stale이란 최신화가 필요한 데이터라는 의미로, stale한 상태가 되면 다음의 경우에 refetch된다.

  • 새로운 query instance가 mount될 때 (page 이동했다가 왔을 때)
    • refetchOnMount
  • 브라우저 화면을 이탈했다가 다시 focus 할 때
    • refetchOnWindowFocus
  • 네트워크 재연결 될 때
    • refetchOnReconnect
  • 특별히 설정한 refetch interval에 의한 경우 (refetchInterval)

❓ 그렇다면 refetch를 어떻게 막을 수 있는가?

  1. refetchOnMount, refetchOnWindowFocus 등의 옵션을 기본 refetch 설정을 막을 수 있음
  2. staleTime 옵션으로 설정한 시간 동안 데이터가 stale 되지 않도록 해 refetch 를 막을 수 있음

🤓 즉, staleTime을 지정해주지 않으면 캐싱 기능을 활용할 수 없다

useQuery 호출 당시 옵션으로 staleTime 을 따로 지정해주지 않으면, default 값인 0 으로 인해 항상 캐싱되어 있는 데이터를 stale하다고 판단하여 계속해서 refetch를 수행한다.

🧐 staleTime을 언제 사용해야 하나?

  • 데이터 구조가 자주 변하는 어플리케이션이라면 staleTime 을 지정하지 않는 편이 좋고,

  • 브라우저에 표현되는 내용의 데이터들이 정적이라면 staleTime 을 지정해주고 적절한 타임에 refetch를 수행하여 서버의 부담을 경감시켜주는 것이 좋다.

📌 enabled 옵션 & refetch 함수

  • enabled 는 쿼리가 ✨자동✨으로 실행되지 않도록 할 때 설정한다.

    • false 일 경우 자동 실행되지 않는다.

    • useQuery return 데이터 중 status 가 idle 상태로 시작한다.

    • enabled: false 이라면 queryClient 가 쿼리를 다시 가져오는 방법 중 invalidateQueriesrefetchQueries 를 무시한다.

      • 즉, 초기 마운트 시 useQuery 가 fetcher 함수를 호출하고(useEffect 처럼), 실패 시 수행하는 retry 를 사전 차단할 수 있다.

      • ❗️ 하지만, enabled: false 는 말 그대로 useQuery의 기능을 사용하지 않겠다는 의미와 같으므로 수동적으로 호출하는 방식이 필요하고, 그것이 바로 ✅ refetch 함수다.

  • refetch 는 쿼리를 ✨수동✨으로 다시 요청하는 기능이다.

    • 쿼리 오류가 발생하면 오류만 기록된다. 오류를 발생시키려면 throwOnError 속성을 true로 해서 전달해야 한다.
  • 📌 보통 자동으로 쿼리 요청을 하지 않고 버튼 클릭이나 특정 이벤트를 통해 요청을 시도할 때 사용한다.

🤓 refetch 함수의 개념

refetch 함수는 캐싱 결과는 조회하지 않고 네트워크 요청을 날리는 함수다.

refetch 함수는 캐싱 결과를 조회하지 않고 무시한다.

즉, 캐싱 내용에 해당 요청 값의 키가 존재하더라도 무시하고 refetch를 수행한다.

🧐 캐싱을 구현하려면?

enabled 옵션을 false로 두면 안된다.

❗️즉, enabled true인 상태 & 캐싱을 구현해야 한다. HOW?

  1. enabled option에 대해 특정한 상태를 충족할 때만 true로 만들고 그 외에는 false로 하여 초기 요청을 통한 retry로 오류를 생성하는 것을 막는다. (refetch 메서드로 강제 호출을 하지 않는다.)
  2. 특정 상태 충족 시 enabled true로 요청을 날림 + 성공하면, data property에 그 값이 저장되고, 캐싱에도 저장이 된다.
  3. 이 data를 가지고 UI를 그려내는 작업을 진행하면 된다.

⏳ cacheTime

🔵 default 값: 5분

캐시 구조에 저장된 데이터는 메모리 상에 존재한다.

🔴 cacheTime이란?

데이터가 inactive 상태일 때 캐싱된 상태로 남아있는 시간

  • query instance 가 unmount 되면 데이터는 ❗️inactive 상태로 변경되며, 캐시는 cacheTime 만큼 유지된다.

  • cacheTime이 지나면 가비지 콜렉터로 수집된다.

  • cacheTime이 지나기 전에 쿼리 인스턴스가 다시 mount 되면, 데이터를 fetch하는 동안 캐시 데이터를 보여준다.

  • cacheTime은 staleTime과 관계없이, ❗️무조건 inactive 된 시점을 기준으로 캐시 데이터 삭제를 결정한다.

  • staleTime을 길게 설정하더라도 cacheTime이 짧다면 이 또한 캐싱이 원활하게 진행되지 않을 것이다. 결국에는 두 개의 옵션을 적절하게 설정해줘야 한다.

📌 retry

const result = useQuery(["todos", 1], fetchTodoListPage, {
	retry: 10, // 오류를 표시하기 전에 실패한 요청을 10번 재시도합니다.
});
  • retry는 쿼리가 실패하면 useQuery를 특정 횟수(기본값 3)만큼 재요청하는 옵션이다.
  • retry가 false인 경우, 실패한 쿼리는 기본적으로 다시 시도하지 않는다.
  • true인 경우에는 실패한 쿼리에 대해서 무한 재요청을 시도한다.
  • 값으로 숫자를 넣을 경우, 실패한 쿼리가 해당 숫자를 충족할 때까지 요청을 재시도한다.

참고

profile
Make your lives Extraordinary!

0개의 댓글