React Query의 공식문서의 주요 내용을 정리한 글입니다. |
React Query란
리액트 쿼리는 리액트 웹앱에서 서버의 상태(state)를
가져오기(fetching), 캐싱(caching), 동기화(synchronizing), 업데이트(updating)를 수행합니다.
React Query 개발 동기
일반적으로 리액트 어플리케이션은
컴포넌트로부터의 데이터 가져오기 혹은 업데이트하는 방식을 제공하지 않습니다.
그래서 개발자들은 제각각 데이터를 자기만의 방식으로 가져오고 업데이트 합니다.
(Promise와 async&await로 처리하거나 전역 상태관리 라이브러리를 사용해 비동기 다루는 방식)
이때 아래와 같은다양한 이유로 어플리케이션과 서버간의 관계와 실시간 상태를 관리하는게 어렵습니다.
- 서버에서 데이터를 가지고 있기에 어플리케이션에서 이를 제어하거나 소유하지 않습니다.
- 데이터를 가져오거나 업데이트하기 위해서 비동기 API가 필요합니다.
- 공유되는 데이터의 경우, 사용자가 모르는 사이에 다른 사용자에 의해 변경될 수 있습니다.
- 어플리케이션내 데이터가 만료(out of date)되어 이전 데이터를 보여줄수도 있습니다.
이런 문제를 방지하기 위해 서버의 상태를 어플리케이션에서 유지하기 위해선
아래와 같은 해결과제들이 나타납니다.
- 캐싱
- 동일한 데이터에 대한 여러 요청의 단일 요청화
- 백그라운드에서 만료된 데이터 업데이트
- 데이터가 만료됨을 인지하기
- 신속한 데이터 업데이트
- 데이터 lazy loading이나 pagination과 같은 성능 최적화
- 서버에서 가져온 상태의 메모리 관리 및 가비지 콜렉션
- 구조적 공유를 이용한 query 결과 memorizing
이런 해결과제를 일일히 해주는건 많은 노력이 소요됩니다.
이때, 리액트 쿼리를 사용하면 아래와 같은 장점을 이용해 위와 같은 해결과제들을 해결할 수 있습니다.
- 앞서본 해결과제들을 위한 수많은 복잡한 코드들을 제거하고 몇줄의 로직으로 대체 가능합니다.
- 새로운 기능을 구현할때 기존 기능에서 사용되는 상태에 대한 추가적인 관리 걱정이 없습니다.
- 빠른 응답 및 대역폭 절약 및 메모리 성능 향상이 가능합니다.
설치하기
$ yarn add react-query
React Query 기본 개념
리액트 쿼리 공식문서에서 가장 기본이 되는 개념으로 아래 3가지를 소개하고 있습니다.
1. useQuery
2. useMutation
3. Query Invalidation
React Query DevTool
import { ReactQueryDevtools } from 'react-query/devtools'
쿼리들의 모든 내부 작업을 시각화하는데 도움이되는 도구입니다.
React Native를 지원하지 않습니다.
NODE_ENV === 'development'의 경우에만 번들에 포함됩니다.
- 플로팅 모드
웹앱에서 devtool을 고정된 위치에 마운트 한후, 모서리에 표시여부 토글을 제공합니다.
이 토글 상태는 localstorage에서 기억하고 있습니다.
최대한 앱의 페이지 루트에 가까울수록 더 잘 작동합니다.
import { ReactQueryDevtools } from 'react-query/devtools' function App() { return ( <QueryClientProvider client={queryClient}> {/* The rest of your application */} <ReactQueryDevtools initialIsOpen={false} /> </QueryClientProvider> ) }
[devtool 플로팅 모드 options]
- initialIsOpen : boolean. devtool 여닫기 여부를 결정합니다.
- panelProps : className, style과 같은 prop를 패널에 추가할 수 있습니다.
- closeButtonProps : 닫기 버튼에 className, style과 같은 props를 추가해주기 위해 사용합니다.
- tooglebuttonProps : 토글 버튼
- position? : 기본은 bottom-left, "top-left" | "top-right" | "bottom-left" | "bottom-right" - 임베드 모드
devtool을 하나의 일반적인 컴포넌트처럼 임베드 할 수 있습니다.
import { ReactQueryDevtoolsPanel } from 'react-query/devtools' function App() { return ( <QueryClientProvider client={queryClient}> {/* The rest of your application */} <ReactQueryDevtoolsPanel style={styles} className={className} /> </QueryClientProvider> ) }
다른 도구와의 비교
앞서 기존의 상태관리 (Context API, Redux 등)와 비교해서 리액트 쿼리가 가지는 장점에 대해 보았습니다.
그러면 비슷한 역할을 수행하는 다른 도구와의 차이는 무엇이 있을까요?
공식 페이지에서 SWR, Apollo client, RTK-query 와 같은 다른 도구와의 비교를 소개하는 내용이 있습니다.
1. React query vs SWR
- React Query는 DevTool을 제공하는 반면에, SWR은 공식 지원 Devtool이 없습니다. (서드파티는 존재)
- 관련 툴중 React Query의 사용량이 많아 커뮤니티가 더 큽니다
- 번들 사이즈는 SWR이 3배정도 더 작습니다.
- React Query는 cacheTime을 통한 가비지 컬렉팅 시간을 설정할 수 있지만, SWR은 불가능합니다.