본문 바로가기

CS/테코톡

React-Query에 대해 알아보자

728x90

목차

  1. React Query는 무엇인가
  2. React Query와 캐싱
  3. Query의 상태 흐름도
  4. react query 사용법
  5. react query 구조

React Query? TanStack Query?

React Query는 v4부터 React를 제외하고도 다른 프레임워크를 지원하여 TanStack Query로 이름을 변경하였다.

하지만 아직 공식 문서에도 React Query라 명시되어있으므로 여기서는 React Query라 하겠다.

React Query가 뭘까?

공식 문서에 의하면 React Query는 강력한 비동기 상태 관리 툴이라고 한다.

상태란(State)?

  • 주어진 시간에 대한 시스템을 표현한 것
  • 문자열, 배열, 객체 등 다양한 형태로 Application에 저장된 데이터

이를 프론트엔드 개발자식으로 풀어보면 다음과 같다.

  • 페이지가 로드되거나 렌더링된 이후 사용자가 수행한 모든 동작의 결과

React Query의 등장 배경

  • 시중에는 이미 많은 상태관리 라이브러리가 있다. 그렇다면 React Query는 왜 나온걸까?

기존 상태 관리 라이브러리는 비동기 및 서버 상태 관리엔 적합하지 않다.

서버 상태란(Server State)?

  • 클라이언트에서 제어하지 않거나 소유하지 않은 위치에서 관리됨
  • fetching 및 updating을 위해 비동기 API 필요
  • 소유권이 공유되므로 사용자가 모르는 사이에 다른 사용자가 변경할 수 있음
  • 주의하지 않으면 애플리케이션에서 "out of date" 상태가 될 수 있음

서버 상태에서 생기는 문제들

  • 캐싱
  • 같은 데이터 요청 중복 제거
  • 언제 'out of date'되는지 알아내기
  • out of date 된 데이터 백그라운드에서 업데이트
  • 최대한 빠르게 업데이트 반영하기
  • pagination, lazy loading 등 성능 최적화
  • 서버 상태의 메모리, garbage collection 관리
  • structural sharing으로 쿼리 결과 memoizing
  • etc...

그렇다면 React Query가 서버 상태를 관리하기 좋은 이유는?

리액트 쿼리와 캐싱

stale-while-revailidate

  • HTTP 캐싱에도 사용됨
  • React Query에 사용되는 캐싱 매커니즘

캐싱된 데이터를 사용자에게 제공하면서, 비동기적으로 콘텐츠를 서버에서 revailidate하는 전략

캐싱 되었을 때와 아닐 때의 차이

캐싱이 안되었을 때


서버에서 이미지를 가져오면서 가져오는 동안 로딩 페이지가 뜨고 이미지를 가져오고나면 정상적으로 출력된다.

캐싱이 되었을 때

캐싱을 하면 로딩 화면이 나오지 않고 미리 캐싱된 데이터를 사용자에게 보여줌, 이후 이미지를 가져오고 나면 정상적으로 출력됨

따라서 오래된 데이터가 데이터가 없는 것보다 더 나은 사용자 경험을 불러올 수도 있음

Query 상태 흐름도

fetching 상태

  • 이 상태는 data fetching이 진행 중인 상태를 나타낸다.
  • React Query는 데이터를 네트워크에서 가져오고 있다.
  • 사용자가 첫 번째로 데이터를 요청할 때 이 상태로 전환된다.

fresh 상태

  • 데이터가 성공적으로 페칭된 후의 상태이다.
  • 이 상태에서는 데이터가 최신 상태로 간주된다.
  • staleTime 동안 이 상태가 유지된다.
  • staleTime이 지나기 전까지는 재페칭을 하지 않고, 캐시된 데이터를 사용한다.

stale 상태

  • staleTime이 지난 후의 상태이다.
  • 이 상태에서는 데이터가 오래된 상태로 간주된다.
  • 이 상태에서도 캐시된 데이터를 사용할 수 있지만, 데이터가 재페칭될 가능성이 높다.
  • 일반적으로 이 상태에서는 백그라운드에서 데이터를 재페칭하는 경우가 많다.(stale-while-revalidate)

inactive 상태

  • 쿼리가 사용되지 않게 된 상태이다.
  • 컴포넌트가 언마운트되거나 더 이상 데이터가 필요하지 않으면 이 상태로 전환된다.
  • cacheTime 동안 이 상태가 유지된다.

delete 상태

  • cacheTime이 지나면 캐시된 데이터가 삭제된다.
  • 이 상태에서는 캐시가 비워지고, 쿼리 키와 관련된 모든 데이터가 삭제된다.
  • 데이터가 다시 요청되면 fetching 상태로 돌아간다.

이 흐름을 통해 React-Query는 데이터 페칭과 캐싱을 효율적으로 관리하여 사용자 경험을 향상시킨다.
오래된 데이터를 빠르게 제공하면서 백그라운드에서 최신 데이터를 유지함으로써 데이터 일관성을 보장한다.

React Query의 사용법

React Query에 대해 알려면 먼저 Query Client에 대해 알아야 한다.

QueryClient

모든 쿼리에 대한 상태 및 캐시를 가지고 있는 클래스
react query를 사용학기 위해서는 필수적으로 생성해줘야 한다.


사진처럼 QueryClinentPrivider에 생성한 QueryClient를 props로 전달하면 하위 컴포넌트에 QueryClient를 제공할 수 있다.

Query Client에서는 전역적으로 옵션을 설정할 수 있다.


이 옵션을 살펴보자

defalutOptions 설정

  • defaultOptions 객체는 쿼리와 변이에 대한 기본 설정을 정의한다.
  • 이 설정은 QueryClient를 생성할 때 제공된다.

queries 설정

  • queries 객체는 모든 쿼리에 대한 기본 설정을 포함한다.
    staleTime : 1000 * 60 : 데이터가 fresh 상태로 유지되는 시간을 60초로 설정한다. 즉, 데이터가 페칭된 후 60초 동안은 stale 상태로 간주되지 않는다.
    retry : 1 : 쿼리 페칭이 실패했을 때 최대 1번 재시도한다.

mutations 설정

  • mutations 객체는 모든 변이에 대한 기본 설정을 포함한다.
  • retry : 변이 작업이 실패했을 때 최대 1번 재시도한다.

이 설정을 통해 모든 쿼리와 변이에 대해 기본 동작을 정의할 수 있다.
이렇게하면 각 쿼리와 변이에서 개별적으로 설정할 필요 없이 일관된 동작을 유지할 수 있다.

Queries 예제

useQuery를 이용해서 query 기능을 사용할 수 있다.
따라서 데이터 페칭, 캐싱, 리패칭 등의 기능을 간편하게 사용할 수 있다.

주의할 점

위의 queryKey와 queryFn이라는 필수옵션은 어떤 값을 세팅하는 걸까?

quertKey

  • 캐시를 관리하기 위한 키값으로 배열 형태로 사용
  • string 형태로 해쉬해 key와 data를 mapping시켜 관리

queryFn

  • promise를 반환하는 함수(fetch, axios 등)
  • data를 resolve하고 error를 던짐

이외에도 Queries의 옵션들이 있다. 몇 가지만 알아보자

  • enabled : 자동으로 query를 실행할지에 대한 여부
  • retry : query 동작 실패 시, 자동으로 몇 번만큼 retry를 시도할 지 결정하는 옵션(기본 값 : 3)
  • select : response 값에서 필요한 값만을 추출할 수 있도록 하는 옵션
  • refetchInterval : 주기적으로 refetch하는 간격을 설정하는 옵션
  • throwOnError : error boundary로 에러를 전파할 지 결정하는 옵션

그렇다면 Query는 최종적으로 어떤 값을 반환할까?

Queries 반환값

  • data : 마지막으로 resolved된 데이터
  • error : 에러가 발생했을 때 반환하는 에러 객체
  • isLoading : 최초 fetch가 in-flight 상태일 때 true 값을 반환
  • isFetching : fetch가 실행될 때마다 true 값을 반환

isLoading과 isFetching은 캐시가 존재하냐 아니냐의 여부로 판단됨

Mutations


crud 중 rud에 해당되며, 주로 서버의 데이터를 수정할 때 사용한다.
옵션의 필수값에 useQuery와 달리 키 값이 들어가지 않은 모습이다.

  • onMutate : mutate 함수가 실행되기 전에 실행되는 함수(좋아요 기능 등에 유용함)

Mutations 반환값

mutate 함수를 반환

  • mutate : mutation 함수를 실행시키는 함수

useQuery와 useMutation에 대해 알아봤으니 v5에 도입된 주요 기능을 알아보자

useSuspenseQuery

React의 Suspense for Data Fetching API(데이터를 불러오는 동안 fallback UI)를 대신 보여주는 기능


기존에는 useQuery의 suspense 옵션을 true로 설정하여 사용했으나

하지만 data는 항상 성공하는데 문제는 undefined로 반환될 수 있다는 문제가 있다.


하지만 이제 useSuspenseQuery를 사용함으로써 데이터 타입을 보장할 수 있다.
단 Query와 다르게 enabled, placeholderData 옵션을 사용할 수 없다.

React-Query는 어떻게 데이터를 저장하고 있을까?

React-Query는 데이터를 저장하고 있으면서 또한 전역적으로 사용할 수 있는 것처럼 보인다.
바로 Context API를 사용하기 때문이다.

좀 더 자세히 알아보자

먼저 컴포넌트에서 useQuery가 실행되면 생성된 Query 인스턴스와 함께 key 값으로 mapping 시키는 과정을 거친다.

이후 fetch된 데이터를 query 객체 내부에 저장한다.


context를 사용했기 때문에 저장된 캐시값은 다른 컴포넌트에서도 사용할 수 있다.

'CS > 테코톡' 카테고리의 다른 글

프론트엔드 성능 측정  (2) 2024.12.06
리액트 렌더링 최적화  (1) 2024.12.06
CSS 프레임워크(Tailwind)  (1) 2024.12.06
쿠키와 웹 스토리지  (0) 2024.12.06
Flux Architecture  (0) 2024.12.06