요번한주를 개인적으로  정리하는 글입니다

 

React-Query 알아보기 및 사용하기

 

리액트 쿼리란?

React Query 는 종종 React에 대한 누락된 데이터 가져오기 라이브러리로 설명이됩니다만 기술적인 용어로 말하면 React 애플리케이션에서 서버상태 가져오기, 캐싱 , 동기화 및 업데이트를 쉽게만듭니다

 

만들어진 동기 

  • React 애플리케이션에는 구성 요소에서 데이터를 가져오거나 업데이타흐난 독창적인 방법이 제공되지않으므로 개발자는 데이터를 가져오는 고유한 방법을 구축해야함
  • 대부분의 기존 상태 관리 라이브러리는 클라이언트 상태 작업에 적합하지만 비동기 또는 상태 작업에는 그다지 좋지않음 ( 서버의 상태가 완전히 다르기 때문 )
    • 서버 데이터는 항상 최신 상태임을 보장하지않음 ( fetching 을 수행해야만 최신 데이터로 전환됨 )
    • 네트워크 통신은 최소한으로 줄이는게 좋은데 복수의 컴포넌트에서 최신데이터를 가져오기 위해 fetching을 여러번 수행하는 낭비가 발생할수있음  

react 에서 비동기를 다루는 방법은 다양합니다

JavaScript 언어이니 당연히 Promise, async & await 으로 처리가 가능합니다

redux 를 사용하고 있다면  redux saga , thunk 등 다양한 미들웨어가 제공됩니다

하지만 이러한 방법들을 사용한다면 서버의 상태를 관리하기가 어려운일이라고 합니다

 

서버의 상태란

 

  • 제어하거나 소유하지 않는 위치에 원격으로 유지됨
  • 가져오기 및 업데이트를 위한 비동기 API 필요
  • 공유 소유권을 의미하며 사용자 모르게 다른 사람이 변경할 수 있음
  • 주의하지 않으면 애플리케이션이 잠재적으로 오래된 상태가 될수 있음

React query 에서 제공하는 것

 

  • 캐싱  ( stale, inactive )
  • 서버 데이터 중복 요청 제거 
  • 만료된 데이터를 백그라운드 상태에서의 업데이트
  • 데이터의 유효시간을 설정하고 유효 시간이 지난 것을 아는것
  • 병렬적 요청 수행
  • 서버상태이 메모리 관리 및 가비지 콜렉션
  • 페이지네이션 , lazy loading 의 성능 최적화
  • 편리한 디버깅 툴
  • SSR, Next.js 지원

이러한 기능들이 없어도 앱을 구현할수는 있습니다

하지만 높은 품질의 앱을 위해서는 필요한작업이라 할 수 있습니다

React Query 는 위와 같은 기능을 사용할 수 있도록 도와줍니다

 

React Query 사용해보기

 

 

yarn create react-app my_react_query
cd my_react_query
yarn add react-query

캐시를 관리하기위하여 QueryClient 를 변수에 담아 만들어둡니다

QueryClientProvider 로 감싸  QueryClientProvider 안의 모든 것에 queryClient에 접근할수있도록 감싸줍니다

 

React Query 에서 가장 환영받는 부분 중 하나는 전용 devtools 세트와 함께 제공된다는 것입니다

React Query 의 devtools를 사용하려면 다음을 연결해줘야합니다 

import { ReactQueryDevtools } from "react-query/devtools";

function App() {
  return (
    <>
      <GlobalStyle />
      <Router />
      <ReactQueryDevtools initialIsOpen={true} />
    </>
  );

React Query devtools 사용 화면

 

 

React Query 사용법

 

React Query 를 통해 관리하는 쿼리 데이터 ( Query, useQuery 가 반환하는 객체 속성값 ) 는 4가지 상태를 가집니다

fetching -> fresh -> stale -> inactive -> delete

- fetching : 데이터 요청하는 상태인 쿼리 

 

- fresh : 데이터가 프레시한 ( 만료되지 않은 ) 상태

  • 컴포넌트의 상태가 변경되더라도 데이터를 다시 요청 하지 않는다
  • 새로고침 하면 다시 fetching 한다

 

- stale : 데이터가 만료된 상태

  • 데이터가 만료되었다는 것은 서버에서 한번 프론트( 클라이언트 )로 데이터를 주면 그 사이에 다른 유저가 데이터를 추가 , 수정 , 삭제 등등 할수 있기떄문에 만료되었다고 한다 ( 최신화가 필요한 데이터 )
  • 컴포넌트가 마운트 , 업데이트되면 데이터를 다시 요청합니다
  • fresh 에서 stale 로 넘어가는 시간 -> 기본값 0 

 

- inactive : 사용하지 않는 상태  

  • 일정 시간이 지나면 가비지 콜렉터가 캐시에서 제거함
  • 기본값 5분

-delete : 가비지 콜렉터에 의하여 캐시에서 제거된 커리

 

 

React Query 는 데이터 패칭, 데이터 동기화 , 데이터 업데이트 , 데이터 캐싱을 도와주고 두개의 훅과 하나의 유틸리티 함수로 작성할 코드 양을 줄여줍니다

 

React Query 사용 전 코드 

const [coins, setCoins] = useState<CoinInterface[]>([]);
 const [loading, setLoading] = useState(true);
 useEffect(() => {
  (async () => {
  	const response = await fetch("https://api.coinpaprika.com/v1/coins");
    const json = await response.json();
    setCoins(json.slice(0, 100));
    setLoading(false);
 	})();
 }, []);
 
 위의 useState<CoinInterface[]> 는 TypeScript 로 사용되어 추가된 부분

React Query 사용 후 코드 

const { isLoading, data } = useQuery<ICoin[]>("allCoins", fetchCoins);

   위의 useQuery<ICoin[]> 는 TypeScript 로 사용되어 추가된 부분

 

React Query 를 사용하기위해서 첫 단계로 fetcher 함수를 만들어 줘야합니다

기존에는 useEffect 에서 사용하여 

async () => {
       const response = await fetch("https://api.coinpaprika.com/v1/coins");
       const json = await response.json();
       }

위와같이 사용해줬지만

 

export async function fetchCoins() {
    const response = await fetch(`https://api.coinpaprika.com/v1/coins/${coinId}`)
    const json = await response.json();
    return json;

}

위 fetcher함수는 json data ( json data Promise )를 return 해줘야함

위와같이 변경하여 redux에서 따로 빼서 공통으로 관리하듯 Api 파일에 위 코드를 만들어 사용합니다

 

const {isLoading, data} = useQuery("allCoins", fetchCoins)

위 코드에 대한 설명입니다

 

1. api.ts의  fetcher 함수를 불러오기위해 임포트를 해줘  fetchCoins를 사용하게해줍니다

2.  uswQuery 라는 훅을 react-query 에서 임포트하여 사용할 준비를함

  • useQuery는 2가지 argment를 필요로함
    • queryKey = query의 고유 식별자
    • fetch 함수 = api.ts 에다 만든 fetchCoins 함수

3. React Query 의 옵션중 isLoading 값을 사용합니다

  • React Query 의 옵션중 isLoading 는 boolean 값을 반환함( 전에 사용되던 코드에서 loading 및 setLoading 등을 데체 가능함 ) 

4. useQuery는 키와 데이터를 불러오는 비동기 함수를 인자로 받아 어플리케이션의 현재 상태를 나타내는 다양한 값을 반환합니다

  • useQuery 훅은 argment의 2번째인자에 작성된 fetcher( fetchCoins ) 함수를 부른다
  • fetcher함수가 loading 중이라면 react query 는 여기서 fetching {isloading} 로 진행중으로 알려준다
  • fetcher 함수가 끝나면 fetcher 함수에서 반환되는 json 값을 data 에 넣어준다
  • 처음 로딩시에 데이터를 가져오는동안 loading 가 보이고 로딩 완료시 데이터가 보이며 데이터는 캐시에 저장된다
  • 데이터가 업데이트 ( 변화 ) 되지 않은 상태에서  전화면으로 이동후 같은 데이터로 접속시 loading이 되지않고 저장되어있는 캐시에서 불러와 데이터를 보여준다
  • 리액트 쿼리는 데이터를 유지하고있는다 ( 리액트 쿼리는 api로부터 데이터를 ( reponse )  받아 캐싱( 저장 ) 함
 
추후 더 추가될예정

'프로그램 시작후 각 주차 정리' 카테고리의 다른 글

공부 13주차 - part 2 ( React-Hook- Form )  (0) 2022.06.05
공부 13주차 - part 1 ( ApexCharts , Recoil )  (0) 2022.06.04
공부 11주차  (0) 2022.05.22
공부 10주차  (0) 2022.05.15
공부 9주차  (0) 2022.05.07

+ Recent posts