-
[React Query] (1) React Query 시작하기Front-End(Web)/React - 라이브러리들 2022. 7. 25. 18:55반응형
🧐 서론
React에서 사용되는 기술들에 계속해서 관심가지던 도중, 최근 React Query를 통한 API fetching이 많다는 것을 느꼈다.
대게 라이브러리들이 그렇듯, 기존의 fetch() 함수나 axios에 비해 더 많은 기능을 제공할 것이라 생각된다. (패치상태, 캐싱 등)
또한, Redux의 경우를 생각하면 비동기 패치와 상태관리 등을 위해 서드파티 라이브러리 설치가 필수적이었다.
(비동기 패치를 위한 Redux-thunk, Redux-saga, 상태관리를 위한 Redux-toolkit 등)
그렇지 않아도 번거로운 Redux 설정이 서드파티로 인해 더욱 비대해지고, 범용적으로 쓰이는 saga는 제너레이션 문법이 요구된다는 등의 사용성 이슈가 존재한다.
유튜브 강의 전개내용을 적당히 분할하면서 정리하며, 우선 React-Query를 사용하는 배경과 세팅방법을 알아보자!
* https://www.youtube.com/watch?v=VtWkSCZX0Ec&list=PLC3y8-rFHvwjTELCrPrcZlo6blLBUspd2
🌺 React Query 란?
공식문서는, React에서 데이터의 fetching, caching, synchronizing, updating server state를 위한 라이브러리라고 정의한다.
즉, axios처럼 단순히 API fetching의 목적보다는, 이 데이터와 더불어 서버 상태(server state)를 관리하는 라이브러리인 것이다.
- 왜 React Query를 사용하는가?
통상 Redux, Recoil 등의 Store에서 관리하는 client state와 달리, server state에는 아래와 같은 내용들이 포함된다.
- Client에서 제어하거나 소유되지 않은 원격의 공간에서 관리되고 유지됨
- Fetching이나 Updating에 비동기 API가 필요함
- 다른 사람들과 공유되는 것으로 사용자가 모르는 사이에 업데이트 될 수 있음
- 앱에서 사용하는 데이터가 "유효기간이 지난" 상태가 될 가능성을 가짐
상품목록, 게시판 댓글, 진행상황 등 지속적인 업데이트로 최신 상태를 유지해야하는 기능들은 위와 같은 특성을 지닌다.
그렇기에, 아래와 같은 내용들이 화두에 오르게 된다.
- 캐싱
- 서버 데이터 중복 호출 제거
- 만료된 데이터를 백그라운드에서 제거
- 데이터의 만료시점 인지
- 만료된 데이터의 업데이트
- Pagination, Lazy Loading 등의 성능 최적화
- Server State의 메모리 관리, 가비지 콜렉션
- 쿼리 결과의 구조 공유를 통한 메모이제이션
이러한, API fetching과 이에 관한 Server State를 "Client 혹은 Store에서 관리하는 것이 적합하지 않다"는 것이 React Query가 출범하는 동기가 되었다.
비동기 패칭과 데이터를 Client 측에서 관리하지 않고(기존의 useState, useEffect) Server State로서 별도로 관리한다는 점,
그리고 데이터의 캐싱, 업데이트, 최적화 등을 위한 솔루션으로 React Query가 선택되고 있다고 이해를 하면 될 것이다!
* 들어가기에 앞서, 대기업들의 FE팀들이 React-Query를 도입하게 된 배경들의 포스팅을 읽어볼 것을 추천한다!
React-Query로 패치를 분리하는 논리와 편의성들이 잘 설명되있다. - (위) 우아한형제들 기술 블로그, (아래) 카카오페이 기술 블로그
- 설치
NPM 설치 혹은 CDN 모듈 2가지 모두 가능하다.
$ npm i react-query $ yarn add react-query
<script src="https://unpkg.com/react-query/dist/react-query.production.min.js"></script>
- 설정
// src/index.js import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import { QueryClient, QueryClientProvider } from "react-query"; import { ReactQueryDevtools } from "react-query/devtools"; const queryClient = new QueryClient(); // 인스턴스 생성 ReactDOM.render( <React.StrictMode> <QueryClientProvider client={queryClient}> {/* devtools */} <ReactQueryDevtools initialIsOpen={false} position="bottom-right" /> <App /> </QueryClientProvider> </React.StrictMode>, document.getElementById("root") );
다음으로 어플리케이션 최상위에 설정하는 방법이다.
먼저, 캐시를 위한 QueryClient() 인스턴스와, 여기에 접근이 가능도록 해주는 <QueryClientProvider> 를 각각 설정해준다.
* React Query Devtools
예제와 같이, React Query 개발자 도구를 사용한다면 <QueryClientProvider> 안에 <ReactQueryDevtools>를 추가하면 된다.
Navigating 컴포넌트처럼 제공되며, 아래와 같은 옵션들을 줄 수 있다.
- initialIsOpen(Boolean) : 최초에 열려있는지 여부. 기본값은 false.
- panelProps(PropsObject) : 개발자 도구 컴포넌트에 className, style 등 Props 제어.
- closeButtonProps(PropsObject) : 개발자 도구 닫기버튼 컴포넌트에 className, style, onClick 등 Props 제어.
- toggleButtonProps(PropsObject) : 개발자 도구를 토글하는 로고버튼 컴포넌트에 className, style, onClick 등 Props 제어.
- position : 개발자 도구를 여는 로고버튼 위치. top-left, top-right, bottom-left(기본값), bottom-right 중 선택.
더 자세한 설명은 공식문서를 참고하자! (링크)
🌺 React Query 기본개념
이제, React Query를 본격적으로 사용하기 앞서 선행적으로 알면 좋은 개념들을 짚고 넘어가겠다.
- LifeCycle(라이프 사이클)
React Query를 통해 관리되는 쿼리 데이터는 라이프 사이클에 따라 각 상태를 가진다.
- fetching : 요청중인 쿼리
- fresh : 만료되지 않은 쿼리. 컴포넌트가 마운트, 업데이트 되어도 데이터를 재요청하지 않음
- stale : 만료된 쿼리. 컴포넌트가 마운트, 업데이트되면 데이터를 다시 요청한다
- inactive : 사용하지 않는 쿼리. 일정 시간이 지나면 가비지 컬렉터가 캐시에서 제거
- delete : 캐시에서 제거된 쿼리.
- 주요컨셉
공식문서에서는, React Query의 3가지 주요 컨셉들로 아래를 소개한다.
- Queries : 비동기 데이터에 대한 선언적 종속성(declarative dependency). Unique Key를 가지며, GET, POST 메서드와 연관
- Mutations : Create, Update, Delete 등 서버 데이터의 수정과 관련된 기능
- Query Invalidation : 캐싱된 쿼리 데이터가 유효한지 여부를 판단하는 개념.
- React Query의 기본설정
React Query에서 제공하는 API들은 아래와 같은 디폴트 설정들을 제공한다.
- useQuery(와 useInfiniteQuery)로 가져온 데이터는 기본적으로 stale 상태. (staleTime 옵션으로 만료를 지연시킬 수 있음)
- stale 쿼리는 아래와 같은 경우에 백그라운드에서 다시 가져온다.
- 새로운 쿼리 인스턴스가 마운트되었을 때
- 브라우저 윈도우가 다시 포커스되었을 때
- 네트워크가 다시 연결되었을 때
- refetchInterval 옵션이 있을 때
- 활성화된 useQuery(와 useInfiniteQuery) 인스턴스가 없는 쿼리 결과는 "inactive" 라벨이 붙으며 다음 사용까지 남아있는다.
inactive 쿼리는 300초(5분) 후에 메모리에서 해제된다. - 백그라운드에서 3회 이상 실패한 쿼리는 에러처리 된다. (retry 옵션으로 재시도 횟수, retryDelay 옵션으로 재시도 대기시간 설정)
- 쿼리결과는 memoization 을 위해 structural sharing(구조상 데이터들을 공유, 원본 유지)을 사용. 데이터 레퍼런스는 불변.
기술적인 내용보다는 React Query를 도입하는 배경과 그 장점, 그리고 사용하기에 앞서 이해하면 좋을 개념들을 위주로 정리했다.
다음 포스팅부터 Queries, Mutations 등 쿼리 데이터를 다루는 주요 문법들에 대해 본격적으로 정리해보도록 하겠다!
📎 출처
- [공식] React Query 공식문서 : https://react-query-v3.tanstack.com/overview
- [강의] Codevolution 유튜브 강의 : https://www.youtube.com/watch?v=VtWkSCZX0Ec&list=PLC3y8-rFHvwjTELCrPrcZlo6blLBUspd2
- [React Query 개념과 예제] DevKkiri 님의 블로그 : https://devkkiri.com/post/f14703ea-a105-46e2-89e8-26282de36a3a
- [React Query] 기억보다 기록을 블로그 : https://kyounghwan01.github.io/blog/React/react-query/basic/#usequeries
- [React Query] rhostem 님의 블로그 : https://blog.rhostem.com/posts/2021-02-01T00:00:00.000Z
반응형'Front-End(Web) > React - 라이브러리들' 카테고리의 다른 글
[React Query] (3) useQuery() 고급 - Parallel, Dependent, Paginated, Infinite (0) 2022.08.02 [React Query] (2) useQuery() (0) 2022.07.26 [Jotai] React 전역 상태 라이브러리 (0) 2022.03.13 [Recoil] 전역 상태관리 라이브러리 - Recoil 정복기 (0) 2021.12.30 [Redux] Redux-Saga (1) 2021.02.21