SPACE RUMI

Hi, I am rumi. Let's Splattack!

[IT] 프로덕트 개발/React - 리액트

react-query 리액트쿼리를 알아보자 (useQuery, staleTime과 cacheTime)

백루미 2022. 10. 15. 02:47
반응형

react-query 리액트 쿼리의 useQuery를 공부해보자.

what is query? 쿼리란 무엇이냐..

쿼리는 데이터베이스 테이블 or 테이블 조합의 데이터 or 정보에 대한 요청이다.

 

설치 및 세팅

리액트쿼리와 devtools를 설치해준다

 

yarn add @tanstack/react-query
yarn add @tanstack/react-query-devtools

 

QueryClientProvider로 라우터를 감싸주고, 안에 ReactQueryDevtools를 넣어준다. 

import { BrowserRouter } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import Layout from "pages/Layout";
import "./App.css";

const queryClient = new QueryClient();

function App() {
  return (
    <div className="App">
      <QueryClientProvider client={queryClient}>
        <BrowserRouter>
          <Layout />
        </BrowserRouter>
        <ReactQueryDevtools initialIsOpen={false}/>
      </QueryClientProvider>
    </div>
  );
}

export default App;

 

devtools를 추가해주면 상태및 정보를 추적하기 편리하다.

 

useQuery

axios.get fetch함수를 만들어주고 useQuery를 작성한다. 리액트쿼리는 유니크한 키값을 통해 캐싱을 관리한다.

const {isLoading, data, isFetching, isError} = useQuery(["유니크 키값", 키], fetch함수, {옵션})
//(키값을 string으로 적어도 내부적으로 array형태로 동작한다.)
import { useQuery } from "@tanstack/react-query";
import axios from "axios";

const fetchWorkers = () => {
  return axios.get("http://localhost:4000/workers");
}

const Two = () => {
  const { isLoading, data, isError, isFetching } = useQuery(["workers"], fetchWorkers, {
    cacheTime:100000,
    refetchOnMount:true,
    refetchOnWindowFocus:true,
  }); 
  if (isLoading || isFetching) {
    return <h2>Loading...</h2>;
  }
  if(isError){
    return <h2>{error.message}</h2>;
  }
  return (
    <div>
      <h2>React Query</h2>
      {data?.data.map((item: any) => (
        <div key={item.id + item.name}>{item.name}</div>
      ))}
    </div>
  );
};

export default Two;

 

캐싱

fresh - fetching - stale 

fresh : 신선한.. 데이터 상태를 뜻한다.
fetching : 데이터를 가져오는 중
stale : 신선하지 않은.. 캐싱된 데이터 상태를 뜻한다.

 

isLoading은 캐싱되지 않은 상태에서 데이터를 가져오는 중일 때(empty cash일때) true -> false 이고,
isFetching은 데이터를 가져오는 중일 때(캐시여부 안따지고, 데이터가 변경되거나 리패치하거나 할때) true -> false로 변경된다.

리액트쿼리의 cacheTime은, 데이터가 inactive 상태일때, 캐싱된상태로 메모리에 잔류하는 시간이다. 기본값이 5분이다.
쿼리 인스턴스 unmount시, 데이터는 Inactive 상태로 바뀌고, 이후 업데이트 되지않으면 garbage collecting 된다.
데이터가 inactive 상태로 전환된 시점을 기점으로, 시간이 지나면 캐시데이터를 메모리에서 삭제한다.


리액트쿼리의 staleTime은 데이터가 fresh 상태에서 stale 상태로 변경되는 시간이다. 기본값이 0초이다.
fresh상태일때는 데이터가 변경되어도 fetch하지 않는다. (staleTime이 지나지않았다면 fetch 발생하지않음)

react-query에서 staleTime 옵션을 설정해주지않으면, 항상 데이터를 가져오는 즉시 신선하지않은 stale 상태로 전환하여 mount시마다 refetch를 한다. (엄밀히 따지자면 캐싱해놓고 바로 신선하지않은 데이터 취급을 해버리기때문에, 데이터는 캐싱하지만, 계속 새로 캐싱하여 상황에 따라서 캐싱을 하는 의미가 퇴색되어 버린다...)
따라서 계속해서 데이터를 호출해야되는 상황이 아니라면, staleTime 옵션값을 적절하게 적어주자.

 

refetchOnMount는 stale 상태일때, 다시 fetch를 실행한다. (default는 true) "always"값을 주면 mount시 항상 refetch 한다.
refetchOnWindowFocus는 stale 상태일 때 화면이 포커싱되면 다시 fetch를 실행한다.(default는 true) "always" 값을 주면 항상 상태와 상관없이 윈도우 포커싱이 될때마다 항상 refetch를 실행한다.

onError, onSuccess

 const onSuccess = (data) =>{
    console.log('데이터 호출 성공시 출력', data);
  }
  const onError = (error) =>{
    console.log('에러는 3회 fetching 후 error 출력',error);
  }

  const { isLoading, data, isError, error, isFetching, refetch }:any = useQuery(["workers"], fetchWorkers,{
    onSuccess,
    onError, 
  });

 

 

react query의 자세한 옵션 내용은 공식문서를 확인하자.

 

useQuery | TanStack Query Docs

const { data,

tanstack.com

 

반응형