ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [은버지 Study] React-query에 대하여
    프로그래밍/React 2023. 7. 31. 01:34

    react-query를 사용해야 하는 이유는 뭘까? 

    없다면 어떻게 비동기 state를 관리를 할까?

    useEffect로 비동기처리를 할려 생각하고 API를 가져와서 useState로 선언한 곳에 넣어주고 오류를 처리하는 작업도 따로 해주어야하는 번거롭고 boiler plate가 많이 일어나는 일을 거쳐야 한다. 

    이렇게 복잡한 것 말고 데이터 가져오고 관리하고 캐싱하고 하는 React-query한번 써보자

     

     

    1. 기본 설정, Devtools, Options

    • React Query의 설치 및 초기 설정
    v3
    npm install react-query
    
    yarn add react-query
    v4 (latest)
    $ npm i @tanstack/react-query
    
    $ pnpm add @tanstack/react-query
    
    $ yarn add @tanstack/react-query

    이후 <ReactQueryProvider> 를 사용해서 앱 전체에 React Query를 설정하고 컨텍스트를 제공하는 것이 일반적이다.

     

    • React Query의 Devtools의 설치 및 활용 방법

    1. 모듈을 불러온다 import {ReactQueryDevtools} from 'react-query/devtools';
    2. </QueryClientProvider> 가 닫히기 전에 선언을 한다 <ReactQueryDevtools initialIsOpen={false} position='bottom-right' />
    3. 오른쪽 아래에 나타난 꽃모양을 클릭해서 개발자 도구를 열 수 있다.
    4. fresh, fetching, stale, inactive와 같은 Data Fetching State를 확인한다
    5. 왼쪽 꽃의 하단에 나타난 모양을 보고 fetch한 API에 대한 정보를 받아 올 수 있다.
    6. Observer는 해당 API call을 요청하는 observer의 수를 나타내며 페이지 내에서 useQuery call을 한 수이다
    7. Last Update는 마지막으로 query를 불러온 시간, Action 버튼을 활용해 query와 관련된 action을 할 수있고 Data Explorer 탭에서 network에서 확인하던 정보와 Query의 state를 확인 할 수 있다

     

     

    • React-query의 본질과 아키텍쳐

    본질은 data fetching에 있는게 아니다 data fetching은 axios나 fetch를 통해서 하지 react-query는 data-fetching에 초점을 두지 말라

    통신에만 초점을 두지말고 queryFn운 promise를 반환하는 모든 함수를 사용할 수 있다.

    aysnc state mamager로 정의되는 동시에 global state manager인데 querykey를 통해서 어느 컴포넌트든 data를 불러 올 수 있기 떄문임

    ㅁ비동기 상태만을 고려해 만들어진 적정기술이다 그래서 비동기 상태를 다루기 위한 API를 직관적으로 가지ㅗㄱ 있고 구현하고자 하는 기능들을 대부분 라이브러리에서 제공한다

     

    내부는 어떻게 되어있을까?

    queryClientProvider의 client로 주입해서 root가 아닌곳에서도 접근이 가능하게 하는 것이 핵심

    순서는 내부적으로 contextAPI를 사용해서 데이터를 공유하고 이어서 client로 주입한 queryClient를 마운트 시기고 다음에 라이브러리 내부의 QueryClientProvider 구현을 한다

     

     


    2. useQuery

     

    • useQuery의 기본문법
    import { useQuery } from "react-query";
    import axios from "axios";
    
    const fetchSuperHeroes = () => {
      return axios.get("http://localhost:4000/superheroes");
    }
    
    export const RQSuperHeroesPage = () => {
      const { isLoading, data } = useQuery("super-heroes", fetchSuperHeroes);
     // 인자로 써 queryKey, queryFn option 순으로 3가지를 받는다
      if (isLoading) return <h2>Loading...!!</h2>;
    
      return (
        <>
          <h2>React Query Super Heroes Page</h2>
          {data?.data.map((hero) => (
            <div key={hero.name}>{hero.name}</div>
          ))}
        </>
      );
    };

     

    • 주요 return data 와 v4부터의 변화

    data: 요청 성공 시 응답 받은 데이터

    error: 요청 실패 시 에러 정보

    refecth: 수동으로 데이터 refetch를 실행하는 함수 stale이나 cache설정을 무시하고 무조건 refetch를 한다

    status: idle(초기상태) loading(fetch중) error(fetch 실패) success(fetch 성공)

    그 외 : boolean type의 isLoading, isError, isFetching 등등

     

     

    • staleTime, cacheTime, refetchOnMount, refetchOnWindowFocus, Polling, enabled refetch

    staleTime : 캐시된 데이터가 stale상태가 되는데 걸리는 시간으로 query가 stale상태가 된 이후 요청이 들어오면 서버에 새로운 데이터를 요청하고 그 전에 요청이 들어온다면 캐시 된 데이터를 사용한다. default값은 0이다.

     

    cacheTime: 캐시된 데이터가 얼마나 오래 유지 될 지를 지정한다 default값은 5분이다

    refetchOnMount : 처음 마운트 될 때 쿼리를 자동으로 다시 가져오도록 설정한다 default값은 false, true로 설정한다면 컴포넌트가 처음 렌더링 될 때 쿼리가 자동으로 실행되어 데이터를 가져온다 deps가 없는 useEffect와 비슷한 느낌일까 생각한다

    refuetchOnWindowFocus: 기본값은 true이고 크롬을 예로 들면 Tab을 이동해서 다시 돌아올떄마다 자연스럽게 refecthing이 일어나는데 false로 해놓으면 포커스에 상관없이 쿼리를 다시 가져오지 않는다

    polling: 주기적으로 쿼리를 자동으로 가져오는 polling설정을 할 수 있다 pollingInterval 옵션을 사용하며 된다

    enabled : flase로 설정되면 요청을 수행하지 않고 비활성화 되어 캐시된 데이터를 사용하고 기본값은 true이다

     

    cacheTime VS staleTime

    먼저 cacheTime은 데이터가 inactive상태일떄 캐싱된 상태로 남아있는 시간을 뜻하는데 쉽게 말해서 쿼리 인스턴스가 unmount 되면 데이터는 inactive상태로 변해서 cacheTime만큼 유지가 된다 이때 다시 마운트 된다면 stale상태의 데이터를 fetch하는 동안에 캐시데이터(cacheTime이 만료되지 않은) 보여주고 fetch가 완료되면 fresh상태의 query를 보여준다

    cacheTime을 이해하기 위해선 inactive상태를 기억해야겠다

     

    enabled 조건문을 걸어서 특정 조건에서 수행할 수있게 만들수도 있다고 생각이 든다

    댓글

Designed by Tistory.