React Query

jinjoo-jung·2023년 12월 31일
0

React

목록 보기
9/10

React Query

목차
1.React Query란?
2.React Query와 캐싱

3.Query의 상태 흐름도

4.react query 사용법

5.react query 구조

v5.0.0 기준

  • react query는 v4부터 react를 제외하고 Solid.js나 Vue.js 등의 다른 프레임워크도 지원함에 따라 TanStack query로 이름을 바꾸었다.
  • 실제로는 유저들도 그렇고 공식문서에서도 그렇고 react query라는 말을 아직 쓰고 있으므로 이번 글에서는 react query 용어로 사용한다.

공식문서

  • 첫페이지 소개글
아주 강력한 비동기 상태 관리하는 툴
    여기서 상태란?
  • 상태 State란, 주어진 시간에 대한 시스템을 표현한 것
  • 문자열, 배열, 객체 등 다양한 형태로 Application에 저장된 데이터
    -> 프론트 개발자스럽게 표현을 한다면?
페이지가 로드되거나 렌더링된 이후, 사용자가 수행한 모든 동작의 결과.-> 그러면 이 관리를 하는 것이 프론트엔드 개발자가 할 일
  1. 사용자가 어떤 Action을 취한다
  2. 그러면 그 Action에 따라서 State가 변경이 된다.
  3. 그 변경된 상태에 따라 View, 웹 페이지 화면이 변경
  4. 다시 사용자가 그걸 보고 다시 또다른 Action을 취하면 사이클이 완성
    => 이 사이클을 관리하는 것이 상태 관리 (State Management) 라고 한다.

다양한 상태 관리 라이브러리

Redux , Recoil, Zustande 등등 엄청나게 많음
리액트 쿼리는 이거보다 더낫다?
=> 무엇이 다른가
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은 이 문제들을 해결할 수 있다고 한다.

react query

  • react query는 공식문서에서 서버상태를 관리하기 위한 가장 좋은 라이브러리중 하나다
    react query와 캐싱
  • stale-while-revalidate
- HTTP 캐싱에도 사용됨
    * react query에 사용되는 캐싱 메커니즘
    -> 캐싱된 데이터를 사용자에게 제공하면서 , 비동기적으로 콘텐츠를 서버에서 revalidate하면서 만약에 데이터가 out of date됐을 경우에는 백그라운드에서 refetch를 보내고 새로운 데이터로 업데이트를 하는 전략
    ex) 만약에 캐싱되지 않았을 경우 기존에 데이터가 있음. 그러면 서버에 요청을 한다(fetch)
먼저 개발자가 미리 설정한 로딩 스피너가 나타날 수도 있고 아무 화면이 안 나올 수도 있다,fetching이 끝나면 새로운 데이터로 업데이트

  • react query를 써서 캐싱이 된 데이터를 쓸 경우 fetching을 하면 로딩 스피너 등이 나오지 않고 미리 캐싱된 데이터를 사용자에게 보여주고, 끝나면 새로운 데이터로 바뀌게 된다.


  • react query의 개발자들은 오래된 데이터가 데이터가 없는 것보다는 낫다라고 생각했기때문에 이런 전략을 취했다?

Query 상태 흐름도

  • query를 쓰게 되면 상태가 여러 개 변경이 되는데, 먼저 fetching을 하면 데이터가 fresh(말 그대로 신선한 상태, 가장 최신의 상태)된 상태로 바뀌게 된다.
  • 그러면 staleTime에 따라서 상태가 변하게 된다.
-> stale(상한, 오래된)상태로 변한다. 그리고 이상태 에서 데이터를 다시 fetching을 해야 될 경우 다시 fetching을 하고, fresh 상태가 되고 , 그렇지 않고 화면에서 사용되지 않을 경우는
stale -> inactive 상태로 변경이 된다.
    inactive 상태에서도 또 다른 타이머가 돌아가게 되는데, v5에서는 기존까지 있었던 명칭인
cacheTime을 gcTime으로 바꿨다
cacheTime은 뭔가 이름만 보면 굉장히 캐싱 된 타임을, 캐싱 된 지속시간을 설명하는 것 같은데 이게 많은 사용자들에게 혼란을 준다고 생각을 해서 그런지, 좀 더 명환한 gcTime, garbage collect되는 시간을 의미하도록 변경하였다.
  • 예를들어 3초라면, 3초동안 화면에서 사용되지 않는다라고 판단을 하게 되면 캐시에 삭제되면서 아예 깨끗하게 삭제가 된다.

react query의 사용법

QueryClient

  • 모든 쿼리에 대한 상태 및 캐시를 가지고 있는 클래스. react query를 사용하기 위해서는 필수적으로 생성해줘야 한다.
  • queryClient를 선언해주고, QueryClient의 props로 queryClient를 전달해주게 되면 하위컴포넌트에서 QueryClient에 접근할 수 있다.
    QueryClient에서는 전역적으로 옵션을 설정할 수 있다.
    default 옵션을 보면 queries와 mutations에 대한 옵션을 설정해준다.
이 두 가지 개념이 리액트쿼리에서 매우 종요하다.
    Queris
  • 비동기적 데이터의 선언적 의존성이라는 의미로 리액트쿼리 공식문서에서 설명하고 있는데,
쉽게 말하면 서버에서 데이터를 받아올 때 사용하는 기능이다.
  • useQuery를 사용함으로써 query기능을 사용할 수 있다.

  • 주의할 점은 v5 버전부터는 인자를 객체 형태로 전달해 줘야하는 점이다;
그러면 여기 인자로 전달되는 key와 queryFn 옵션이 있는데 이 두 가지 필수 옵션은 어떤 값이 전달?

Queries와 queryFn외에 어떤 옵션?


=> 이러한 많은 옵션을 사용할 수 있는데 몇 가지만 소개해보자.
1. enabled 옵션 : 자동으로 쿼리를 실행할 지에 대한 여부를 결정하는 옵션
기본값은 true로, enabled 옵션이 false로 설정될 경우 쿼리를 자동적으로 실행시켜주지 않는다.
2. retry 옵션

  • 쿼리 동작 실패시 자동으로 몇 번 만큼 다시 시도 할지, 기본값은 3으로 리액트쿼리가 쿼리를 가져오는데 실패했을 경우 총 3번까지 retry를 기본값으로 실행하게 된다
  1. select옵션
  • select는 response 값에서 필요한 값만을 추출할 수 있도록 하는 옵션


  • throwOnError는 true값으로 설정하면 에러 바운더리를 사용할 수 있다.
    => 그러면 최종적으로 Query는 무슨 값을 반환?

    : 데이터와, 에러를 반환
설명에서 보이는 것처럼 result는 데이터는 데이터를 의미하며

    에러는 에러가 발생했을 때 반환하는 error 객체를 의미한다.
    그리고 유용하게 사용할 수 있는 옵션으로 isLoading 옵션과 isFetching 옵션이 있는데 비슷하다.


두가지의 차이점은 캐시가 존재하냐, 아니냐이다.

Mutations

  • curd중에서 rud에 해당하는 기능, 즉 서버의 데이터를 수정하는 사용하는 기능
  • 아까와 비슷하게 useMutation 함수를 선언함으로써 Mutations 기능을 사용할 수 있다.
    이 함수의 필수값에는 아까와 달리 키값이 들어가지 않고 queryFn

Mutations옵션에는 어떤?

  • 대체적으로 Queries와 유사한 옵션이 들어간다.
  • mutate함수는 Mutation가 실행되는 시점에 실행되는 함수인데 만약에 이 함수를 컴포넌트에서 Mutations가 실행되는 시점에 실행 시켜주게 되면 Mutations 기능을 사용할 수 있다.

useSuspenseQuery

v5에 도입된 가장 중요한 기능?

  • Suspense는 데이터를 불러오는 동안 fallback UI를 대신 보여주는 기능인데,
  1. 기존에는 useQuery를 true로 설정함으로써 설정했음.


문제점

  • useSuspenseQuery
  • 데이터 타입을 보장할 수 있었다
    *-쿼리오는 다르게 enabled, placeholderData 옵션을 사용할 수 없음

    또한 throwOnError값을 기본 저장할 수 없으며 만약에 반환되는 데이터가 없을 시 자동으로 에러 바운더리로 error를 전파한다는 차이점이 있다.

그러면 리액트쿼리는 데이터를 어떻게 저장하고 있을까

  • 리액트쿼리는 데이터를 저장하고 있는데 전역적으로 사용할 수 있는 것처럼 보인다.
  • 바로 Context를 사용하고 있기 때문
  • Context API를 사용하기 때문에 useClientProvider 하위에 써놓은 Query들을 서로 공유해서 사용할 수 있는 것이다.




컴포넌트에서 유즈쿼리가 실행이 되면 생성된 쿼리인스턴스와 함께 키값으로 매칭시키는 과정을 거친다,
그리고 fetch된 데이터를 기준으로 쿼리 객체 내부에 저장함으로써 캐시를 관리하게 된다.
Context를 사용했기 때문에 저장된 캐시 값은 다른 컴포넌트에서 사용할 수 있는 것이다.

참고
https://www.youtube.com/watch?v=eBDj0B0HbEQ

profile
개인 개발 공부, 정리용 🔗

0개의 댓글

관련 채용 정보