[React-Query] Section 01

은채·2022년 9월 2일
0
post-thumbnail
post-custom-banner

react-query 강의 정리

상태 차이

Client State

  • 웹 브라우저 세션과 관련된 모든 정보
  • ex. 사용자는 가장 잘 아는 언어로 텍스트를 읽기 위해 언어를 선택하거나, 다크모드 선택 등 => 서버에서 일어나는 일과는 관련 없음
  • 단순히 사용자의 상태 추적

Server State

  • 서버 상태는 서버에 저장된다
  • 클라이언트에 표시하는데 필요한 데이터
  • ex. 데이터베이스에 저장되는 데이터 (게시글)

React-Query

  • 클라이언트에서 서버 데이터 캐시를 관리한다

  • react code에서 서버 데이터가 필요할 때, Fetch, Axios 등을 사용해서 서버로 바로 이동하지 않고 React Query 캐시를 요청

  • 역할 : react-query 클라이언트를 어떻게 구성했느냐에 따라 해당 캐시의 데이터를 유지, 관리하는 역할

  • 데이터를 관리하는 것은 react-query이지만, 서버의 새 데이터로 캐시를 업데이트하는 시기를 설정하는 것은 사용자 역할

예시

'blog-posts'라는 키가 있는 데이터 => 데이터 식별 방식

  • 클라이언트 캐시에 있는 이 데이터가 서버의 데이터와 일치하는지 확인해야 함
  • 방법 2가지
    1) 명령형 : 쿼리 클라이언트에 이 데이터를 무효화, 캐시에 교체할 새 데이터를 서버에서 가지고 오게 명령
    2) 선언형 : 리패치를 트리거(유발)하는 조건 구성 => 브라우저 창이 다시 포커스 되었을 때 => staleTime으로 다시 가져오는 것도 조절 할 수 있음
    (30초 후 브라우저 창이 다시 포커싱 되었을 때 서버에서 새 데이터를 가져오게)
  • react-query에는 상태 관리를 위한 툴이 제공 된다
    1) 서버에 대한 모든 쿼리의 로딩 / 오류 상태를 유지 => 수동 작업 x
    2) 페이지네이션, 무한스크롤에 필요한 데이터 및 도구 제공
    3) 사용자가 필요한 시점을 예상해서 프리패치를 제공
    : 데이터를 미리 가져와서 캐시에 넣어놓고 사용자가 필요할 때 제공 (서버 연결을 기다릴 필요가 없다)
    4) 서버에서 데이터 변이나 업데이트를 관리할 수 있음
    5) 쿼리는 키로 식별되기 때문에 react-query는 요청을 관리 할 수 있고, 페이지를 로드하고 해당 페이지의 여러 구성 요소가 동일한 데이터를 요청하는 경우 쿼리를 한 번에 보낼 수 있음
    : 기존 쿼리가 나가는 동안 다른 구성 요소가 데이터를 요청하는 경우 중복 요청을 제거 할 수 있음
    6) 서버에서 오류가 발생하는 경우에 대한 재시도 관리
    7) 쿼리가 성공, 오류 났을 때를 구별해서 조치를 취할 수 있도록 콜백 전달

react-query ver.3 설치하기

npm install react-query@^3

React Query 버전 4를 사용하시는 경우, 다음과 같은 특이사항이 있다.

  1. 버전 4에서는 설치와 임포트(import)에 react-query가 아닌 @tanstack/react-query를 사용하시는 것을 권장

  2. 쿼리 키는 반드시 배열이어야 하며, 만약 강의에서 문자열을 쿼리 키로 사용하는 경우, 해당 문자열을 반드시 배열 안에 넣어야 함

  3. onSuccess는 더 이상 setQueryData에서 호출되지 않는다.
    이전과는 달리 setQueryData를 호출한 이후에 onSuccess를 호출하는 것으로 작동 순서를 바꾸었기 때문에, 이 상황에서 학습 내용을 버전 4에 적용하시면 문제가 발생

첫번째 프로젝트에서 배울 것

Getting Started

  1. npm install react-query
  2. Create query client
  • 쿼리와 서버의 데이터 캐시를 관리하는 클라이언트
  1. Apply QueryProvider
  • 자녀 컴포넌트에 캐시와 클라이언트 구성을 제공할 QueryProvider 적용
  • 이에 대한 값으로 사용 될 쿼리 클라이언트 필요
  1. Run useQuery
  • 서버에서 데이터를 가져오는 훅

Apply QueryProvider

기존

queryclient와 queryclientprovider를 적용한다.

const queryClient = new QueryClient();


function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <div className="App">
        <h1>Blog Posts</h1>
        <Posts />
      </div>
    </QueryClientProvider>

  );
}



이 쿼리 클라이언트가 있어야, 공급자를 추가 할 수 있게 되고
공급자가 이 클라이언트가 가지고 있는 캐시, 옵션등을 자녀 컴포넌트로 보낼 수 있다.
이제 내부 posts 컴포넌트에서도 react-query와 관련된 hook을 사용할 수 있게 된다.

하드 코딩 된 data가 아닌 useQuery를 활용하여 데이터를 가져오게 된다.

useQuery와 함께 사용해야 할 몇 가지 인수

1) 쿼리 키 = 쿼리 이름
2) 쿼리 함수 = 쿼리에 대한 데이터를 가져오는 방식 (fetchBoards, fetchPosts = 비동기 함수)

컴포넌트 상단에 쿼리 함수

async function fetchPosts() {
  const response = await fetch(
    'https://~~~~~~~~~'
  );
  return response.json();
}

우리가 매핑 할 데이터는 fetchPosts 에서 반환 된 데이터가 되고 => 위 HTTP 요청에서 반환 된 JSON
=> 비동기 함수이기 때문에, map 실행이 안 될 것.
=> 지금은 if(!data)로 임시방편을 해두자.

데이터가 정의되지 않았을 때 오류로 두지 않고 처리하는 방법은?

isLoading / isError

isLoading 데이터가 로딩중인지 여부
isError 데이터를 가져올 때 오류여부

  • 로딩하는 동안은 loading....가 보인다

  • 에러가 나면... Oops..가 보인다.
    => 리액트 쿼리는 기본값으로 3번 시도한 이후에 오류를 결정한다. (바꿀 수 있음!)

    => 시도하는 중간에는 loading.. 3번 이후에 오류

  • 반환 객체에는 쿼리 함수에서 전달하는 error도 있어서, 활용할 수 있다.

isLoading과 isFetching의 차이점?

isFetching

  • 비동기 쿼리가 해결되지 않았음
  • 페칭을 완료하지 않았다는 의미
  • 쿼리가 axios 호출, 또는 graphql 호출일 수 있다.

isLoading

  • 이에 대한 하위 집합
  • 가져오고 있는 상태, 쿼리 함수가 해결되지 않았음
  • 캐시 된 데이터도 없음 (표시할 캐시 데이터도 없음)
  • 이 쿼리를 만든 적이 없다.

=> 페이지네이션을 진행할 때 캐시된 데이터가 있을 때와 없을 때를 구분해야 하기 때문에 알아야 함

리액트 쿼리 데브 툴

  • 쿼리 키로 쿼리 표시
  • 활성, 비활성, 만료 등의 모든 쿼리 상태를 알려줌
  • 업데이트 된 타임스태프 확인
  • 쿼리에 의해 반환된 데이터를 탐색할 수 있음
  • 쿼리를 볼 수 있는 쿼리 탐색 가능
  • 개발 중에만 표시, 프로덕션에는 표시되지 않음

데브 툴을 설치하고, app.jsx

와!

꽃이 생겼다.


내가 불러온 posts 라는 쿼리와 그 내용들, 불러온 시간 등등등의 정보를 볼 수 있다!

Stale Data

stale Data

  • 만료된 데이터
  • 데이터 리패칭은 만료된 데이터에서만 실행된다.
  • 데이터 리패칭 실행에는 만료된 데이터 외의 다양한 트리거가 있다.
    ex) 컴포넌트가 다시 마운트 될 때, 윈도우가 다시 포커스 되었을 때
  • 데이터를 허용하는 '최대 나이'
  • 데이터가 만료되었다고 판단하기 전까지 허용하는 시간 Stale Time
  • 웹 사이트에 표시된 데이터가 10초까지 괜찮다? => Stale Time = 10초 (데이터의 성격마다 다름)
  • 업데이트 하는 방법

useQuery 호출 시, 세 번째 인수 추가하기 (options)

왜 기본값이 0일까? => 데이터는 항상 만료상태이므로, 서버에서 다시 가져와야 한다고 가정하는 것
=> 실수로 클라이언트에게 만료될 데이터를 제공할 가능성이 줄어든다!

stale Time vs cacheTime

  • 캐시는 나중에 다시 필요할 수도 있는 데이터
  • 특정 쿼리에 대한 활성 useQuery가 없는 경우, 해당 데이터는 콜드 스토리지로 이동
  • 구성된 cacheTime이 지나면 캐시 데이터가 만료되며 (유효시간 5분)
  • catchTime이 관찰하는 시간의 양은 특정 쿼리에 대한 useQuery가 활성화 된 후 경과한 시간
  • 페이지에 표시되는 컴포넌트가 특정 쿼리에 대해 useQuery를 사용한 시간
  • 캐시가 만료되면 가비지 컬렉션이 실행되고, 클라이언트는 사용 불가
  • 데이터가 캐시에 있는 동안에는 패칭할때 사용 가능
  • 데이터 패칭을 중지하지 않으므로 서버의 최신 데이터로 새로고침이 가능
  • 하지만 계속해서 빈페이지만 보는 경우 생길 수 있음 => 무슨 데이터인지?
  • 새로운 데이터를 수집하는 동안 약간 오래된 데이터를 표시하는 편이 빈페이지 보다 낫다
  • 만료된 데이터가 위험한 경우에는 cacheTime을 0으로
profile
반반무마니
post-custom-banner

0개의 댓글