[Study] React-Query 정리

박하민·2023년 8월 4일

React 관련 강의를 듣다 보면, React-Query라는 말을 심심치 않게 들을 수 있었습니다.
이름만 봤을 때는 용도를 파악하기 어려웠기에, 바로 공식 문서와 관련 포스팅들을 보며 개념을 정리하고자 합니다.

공식 문서에 개요를 살펴보면

기본적으로 React 애플리케이션은 구성 요소에서 데이터를 가져오거나 업데이트하는 독선적인 방법을 제공하지 않으므로 개발자는 결국 데이터를 가져오는 고유한 방법을 구축하게 됩니다. 이것은
1.일반적으로 React 후크를 사용하여 구성 요소 기반 상태 및 효과를 함께 결합하거나 보다 범용적인
2.상태 관리 라이브러리를 사용하여 앱 전체에서 비동기 데이터를 저장 및 제공하는 것을 의미합니다.

  1. axios 라이브러리를 사용해 서버에서 데이터를 가져오거나 업데이트할 때 React Hooks에서 제공하는 useState, useEffect 등을 활용해 데이터를 관리

  2. 기존에는 다양한 상태 관리 라이브러리(Redux, Recoil, Mobx 등등)에서 지원하는 API 요청 작업 사용이 가능했습니다. 예) Redux-Thunk와 Redux-Saga

Why React-Query??

기존에 많이 사용했던 방법이라 하면 역시 redux를 이용한 redux-thunk & saga를 사용해 비동기 API 요청을 진행하고 데이터를 저장하거나 사용하는 방식이라고 생각합니다. 그런데 redux의 본래 역할을 생각해 보면, react-component의 state를 관리하는 역할입니다.


기존 Redux의 문제점

  1. 가뜩이나 복잡한 redux 코드에 비동기 통신 코드까지 더하게 되어 상태 관리 영역이 서버 데이터를 저장하는 데까지 확장되고 있다.
  • redux-toolkit으로 예전만큼 Boilerplate 코드가 복잡하지는 않지만, 여전히 설정해야 할 부분도 많다.

  • 비동기 통신 관련 코드까지 더하게 된다면 어려움이 많고, 본래의 역할이 아닌 범위까지 확장되어 사용된다.


  1. 서버에서 받아온 비동기 데이터를 react-component의 state에 저장할 경우 Lifecycle에 영향을 받아 캐싱최적화 수행이 어렵다.
  • component의 종류도 매우 많이 존재함에 따라 Lifecycle도 빈번하게 변경 => 매번 서버에 데이터를 요청하고 componet state에서 데이터를 관리하고 사용하는 부분에 있어서 어려움 발생

  • 캐싱이란 일종의 임시 저장 같은 개념으로 특정 데이터의 복사본을 저장하여 이후 동일한 데이터를 반복적으로 호출하는 것을 방지하고, 불필요한 요청과 API 서버에 대한 부하를 줄여 성능 향상에 도움을 준다.

이 부분은 카카오페이 테크 블로크에 이미 잘 정리된 내용이 포스팅되어있어 인용해 보았습니다.

🙌 「if(kakao)2021 - 카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유」 세줄요약 🤟

  1. React Query는 React Application에서 서버 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트하는 작업을 도와주는 라이브러리입니다.
  2. 복잡하고 장황한 코드가 필요한 다른 데이터 불러오기 방식과 달리 React Component 내부에서 간단하고 직관적으로 API를 사용할 수 있습니다.
  3. 더 나아가 React Query에서 제공하는 캐싱, Window Focus Refetching 등 다양한 기능을 활용하여 API 요청과 관련된 번잡한 작업 없이 “핵심 로직”에 집중할 수 있습니다.

React Query, Devtools 설치

react query

npm install @tanstack/react-query

Devtools (Redux DevTools와 비슷한 역할을 수행합니다.

npm i @tanstack/react-query-devtools
# or
pnpm add @tanstack/react-query-devtools
# or
yarn add @tanstack/react-query-devtools

서버에서 데이터를 가져올 때

  • HTTP 메소드의 Get 사용
  • 쿼리 생성 시 작성하는 고유 key를 기반으로 애플리케이션 전체에서 쿼리를 다시 가져오고, 캐싱하고, 공유하기 위해 내부적으로 사용됨
    useQuery,

useQueries,

  • 여러 데이터를 병렬로 가져와야 할 때

useInfiniteQuery,

  • 계속해서 데이터를 가져와야 할 경우 Ex) 무한 스크롤

기본 값으로 설정된 경우 오래된 쿼리는 자동으로 데이터를 갱신합니다. 1. 쿼리를 사용한 컴포넌트가 마운트 되었을 때 2. 윈도우가 다시 포커스 되었을 때 3. 네트워크가 다시 연결되었을 때 4. refetchInterval 설정으로 반복적인 refetch 될 때

쿼리 키

  • v3까지는 문자열 Or 배열로 지정 가능했으나 v4부터는 배열의 형태만 가능

배열 키


#### 쿼리의 상태 1. isLoading 또는 status === loading => 쿼리에 데이터가 없고 현재 가져오는 중
  1. isError 또는 status === error
    => 쿼리에 오류 발생

  2. isSuccess 또는 status === success
    => 쿼리가 성공했고 데이터 사용 가능

  3. isIdle 또는 status === idle (v3까지 지원)
    => 쿼리가 현재 비활성화되어 있음

  4. fetchStatus (v4부터 지원)
    => 쿼리 속 queryFn 요청의 진행 상태를 의미
    => status는 data의 유무에 대한 상태를 의미


공식 문서에서 제공하는 사용 가이드

  • isLoading으로 상태를 확인하고한 다음 isError로 상태를 확인
    => 성공적으로 데이터를 사용할 수 있는 상태
function Todos() {
  const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)

  if (isLoading) {
    return <span>Loading...</span>
  }

  if (isError) {
    return <span>Error: {error.message}</span>
  }

  // We can assume by this point that `isSuccess === true`
  return (
    <ul>
      {data.map(todo => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  )
}

status만으로도 사용 가능합니다.

 if (status === 'loading') {
    return <span>Loading...</span>
  }

  if (status === 'error') {
    return <span>Error: {error.message}</span>
  }

서버의 데이터를 변경할 때

  • HTTP 메소드의 POST, PUT, PATCH, DELETE 사용
    useMutation,

각자 맡은 역할만 수행하자!

  • redux는 react-component에서 발생하는 state를 관리하고,
  • react-query는 server state(서버에서 받는 데이터)를 관리하자!

참고

TanStack Query v4 installation
TanStack Query v4 Devtools
카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유
[React] TanStack Query v4 (React Query)

profile
https://mintmin.dev/ <~~ 블로그 이전했씁니다

0개의 댓글