[react-query] Query Cache란?_02

Olivia·2023년 5월 29일
0

[React-query]

목록 보기
2/2
post-thumbnail

react-query에 가장 중요한 개념 중 하나가 바로 '캐싱'이다.
react-query를 사용하지 않고, 데이터 fetch를 하게 될 경우를 보자.

react-query를 사용하지 않고 데이터 fetch

위의 동영상을 보면 알 수 있겠지만, 데이터 fetch를 하고서 다시 home 화면에 돌아간뒤, 동일한 데이터 fetch 페이지로 돌아갈때마다 계속 로딩이 되는걸 확인할 수 있다. 그러나 react-query를 사용한 페이지는 다르다.

react-query를 사용한 데이터 fetch

반면 `react-query`를 사용하면 데이터 fetch 이후 home 화면에 돌아간 뒤, 동일한 페이지로 돌아가도 로딩이 되지 않는다. 그 이유는 바로 `react-query`에는 **캐싱**이라는 개념이 있기 때문이다. 이전 포스팅에서 사용하던 `react-query`코드를 통해 조금 더 알아보자.
// fetch data using react-query

import axios from "axios";
import { useQuery } from "@tanstack/react-query";
import styles from "./RQProducts.module.css";

const Products = () => {
  const fetchData = async () => {
    const res = await axios.get("http://localhost:4000/products");

    return res.data;
  };

  const { status, data, error } = useQuery(["products"], fetchData);

  if (status === "loading") {
    return <h1>Loading...</h1>;
  };

  if (status === "error") {
    return <h1>Error: {error.message}</h1>;
  };

  return (
    <>
      <h1>React Query Products</h1>
      {data &&
        data.map((product) => {
          return <li key={product.name}>{product.name}</li>;
        })}
    </>
  );
};

export default Products;

1️⃣ useQuery가 처음 "products"(query-key)키를 실행하면, isLoadingtrue로 설정된 후, 네트워크 요청이 전송되어 데이터를 가져오게 된다.
2️⃣ 요청이 완료되면, query-key를 사용하여 캐싱되고 "products"을 고유 식별자로 사용한다.
3️⃣ Products페이지에서 main 페이지로 돌아간뒤, 다시 Products 페이지로 돌아올 경우, react-query는 해당 쿼리에 대한 데이터가 캐시에 있는지 확인한다.
4️⃣ 만약, 데이터가 캐시에 있을 경우, 이 캐시된 데이터는 로드되지 않고 true로 설정되어 즉시 return 된다. 따라서 해당 페이지를 재방문할 경우, "Loading..." 이 더이상 보이지 않는 것이다.
5️⃣ 만약, react-query가 서버 데이터가 변경되었고, 캐시는 최신 버전을 담고있지 않는걸 알게 되면, background refetch가 트리거된다.
그리고 fetch가 성공적으로 끝난다면, 데이터가 업데이트 된다.
위의 경우 isFetching을 통해서 확인할 수 있다.
6️⃣캐시를 지우고 싶다면 {cacheTiem: 시간}을 사용하면 된다.

const { status, data, error } = useQuery(["products"], fetchData{
	cacheTime: 5000,
});

그럼 다시 메인페이지로 돌아갔다가 products 페이지로 돌아와도 Loading이 보이게 된다.

react-query cache

이 캐싱 개념은 stalecachetime을 통해서 이루어진다.
chachetime은 위에서 잠깐 언급했으니 간단하게 정리하고 넘어가겠다.

cacheTime

캐시에 저장된 데이터는 메모리에 남아있게 되는데, 이 캐시는 cacheTime만큼 유지가 된다.
react-query에서 설정한 default 값은 300000(5분)으로, 만약 이 시간동안 사용하지 않으면, 메모리에 저장되는게 불필요하다고 판단해서 garbage collector가 수거해서 캐시에서 해당 쿼리가 삭제된다.

stale

stale의 사전적인 의미는 "탁한", "신선하지 않은" 으로 해석된다.
즉, 데이터가 stale하다는 의미는 데이터가 신선하지 않아 업데이트가 필요하다는 뜻이 된다.
default 값은 0으로, 데이터를 fetch 한 즉시 해당 데이터는 stale한 상태가 된다.
만약, 서버 데이터가 변경이 될 경우, 브라우저의 데이터는 stale한 데이터이기 때문이다.
이런 경우, refetch가 필요한데, refetch가 되는 조건은 다음 아래와 같다.

  • 네트워크가 다시 연결될 경우 👉 refetchOnReconnect
  • 새로운 query instacnce가 마운트 될 경우 👉 refetchOnMount
  • 브라우저 화면이 다시 focus할 경우 👉 refetchOnWindowFocus
  • 특별하게 설정한 refetch interval의 경우 👉 refetchInterval

적절한 staleTime이란?

staleTime은 쿼리를 fetch한 이후, 데이터가 stale한 상태가 되는데까지 소요되는 시간.

💡 여기서 react-queryuseQuery를 통해서 데이터를 fetch할 경우, staleTime을 따로 지정하지 않았을 때 캐시에 저장된 데이터는 stale하다고 생각해서 계속해서 refetch를 하면서 서버에 요청을 한다.
만약 데이터가 자주 바뀌는 어플리케이션일 경우 staleTime을 따로 지정하지 않아도 괜찮겠지만, 만약 잦은 변경이 없는 어플리케이션.일 경우 staleTime을 지정하는 것이 서버의 부담을 줄일 수 있어 좋다.

staleTime을 설정할 경우, cacheTime역시 고려해야한다.

cacheTime: 
캐시에 저장된 데이터는 메모리에 남아있게 되는데, 이 캐시는 cacheTime만큼 유지가 된다.
default: 5분

staleTime:
쿼리를 fetch한 이후, 데이터가 stale한 상태가 되는데까지 소요되는 시간.
default: 0분

위처럼 staleTimedefault값은 0분이기 때문에 데이터가 캐싱되어도 stale하지 않은, 즉 신선한 데이터가 하나도 없다.
따라서 staleTime을 설정하지 않으면 아래의 영상처럼 data를 fetch하자마자 stale이 뜬다.

따라서 staleTime을 설정하면 fresh가 보인다.

이때 cacheTime을 고려해서 설정해야한다.
만약 staleTime을 길게 설정한다고 할지라도 cacheTime이 짧으면, 캐시가 사라진다.
데이터가 stale한 상태가 되면 refetch를 통해 서버에 요청을 해야하는데, cacheTime으로 인해 캐시가 사라지면 refetch가 안되기 때문이다.

profile
👩🏻‍💻

0개의 댓글