드림오구
article thumbnail

🌊 TanStack Query (리액트 쿼리)

 

* 아직 공부 중입니다. 

리액트를 사용하여 개발하면 웹에서 데이터를 받아 관리해야하는 일이 많습니다. React Query, 현재는 이름이 변경된 TanStack Query는 강력한 비동기 상태 관리 라이브러리로, 서버의 데이터를 클라이언트에 가져오거나 캐시를 관리, 데이터 업데이트 등 비동기 과정을 더욱 편하게 하는데 사용됩니다. 

 

예를 들어, useEffect로 데이터를 받아오는 컴포넌트를 만들고 그 컴포넌트를 다른 컴포넌트에서 호출하였을 때, 값을 재사용하거나 같은 상태를 공유하는 것이 아닌, 컴포넌트를 호출하는 여러 컴포넌트를 걸쳐 계속해서 새로운 값을 받아오며 네트워크 통신이 발생하게 됩니다. 따로 캐싱을 관리하지 않아서인데요. TanStack Query는 이것을 관리해주어 더욱 편안하게 비동기 상태를 관리해줄 수 있습니다.

 


TanStack Query는 원래 React-Query로 불리었지만, v4로 업데이트 하며 이름을 TanStack Query로 변경하였습니다.
현재는 리액트 뿐만 아니라 TS/JS, Solid, Vue, Svelte에서도 사용이 가능합니다.

 

Redux 등 다른 상태관리 라이브러리와의 차이점

처음에 저는 이 TanStack Query와 redux와의 차이를 이해하기 어려웠습니다. Redux에서도 비동기 처리가 가능하기 때문에 Redux가 오히려 더 많은 영역을 포괄하여 사용할 수 있는 라이브러리 아닌가? 하는 의문도 들었습니다. 그래서 TanStack Query를 소개하는 글을 쓰며 저는 이 라이브러리의 장점을 어필하기 위해 다른 개발자들은 왜 TanStack Query를 선택했을까 찾아보았는데요. 여러 프론트앤드 개발자들의 주 사용 목적이 store에 클라이언트 데이터와 서버 데이터가 공존하여 서로 상호작용하는 것에 불편함을 느끼게 되어 사용한다고 말합니다. 

 

  TanStack Query Redux
차이점 외부 데이터 관리 특화! 클라이언트 전역 상태 관리

 

TanStack Query는 오직 외부 데이터 관리에 특화되어 있는 라이브러리입니다. TanStack Query로 비동기 작업을 할 시 Redux로 작업할 때 보다 코드의 분량이 훨씬 줄어들어 복잡도를 낮추고 유지보수의 용이성을 높이고, 사이드 이펙트가 생길 확률도 적어집니다. 

 

공식 문서에서는

 

공식문서에서는 TanStack Query를 이렇게 소개합니다.

 

기술적인 측면에서 보면, React Query는 아래와 같은 방식으로 도움이 될 것입니다:

  • 복잡하고 이해하기 어려운 코드를 수많은 줄에서 제거하고, 단 몇 줄의 React Query 로직으로 대체할 수 있게 도와줍니다.
  • 새로운 서버 상태 데이터 소스를 연결하는 데 대한 걱정 없이 애플리케이션을 더 유지보수하기 쉽게 만들고 새로운 기능을 만드는데 더 쉽게 할 수 있게 도와줍니다.
  • 애플리케이션이 이전보다 더 빠르고 반응성이 좋게 느껴지게 함으로써 최종 사용자에게 직접적인 영향을 미칩니다.
  • 대역폭을 절약하고 메모리 성능을 향상시키는데 도움이 될 수 있습니다.

Tanstack Query 공식문서
 

TanStack Query | React Query, Solid Query, Svelte Query, Vue Query

Powerful asynchronous state management, server-state utilities and data fetching for TS/JS, React, Solid, Svelte and Vue

tanstack.com

 

 

TanStack Query 장점

 

  • 캐싱
  • 비동기적으로 데이터 관리시 유용하다.
  • get을 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행한다
    → 게시판 글을 가져왔을 때 게시판 글을 생성하면 게시판 글을 get 하는 api를 자동으로 실행
  • 지속적으로 동기화하고 업데이트 하는 작업을 도와준다.
  • 동일 데이터 여러 번 요청을 하면 한 번만 요청을 한다. (옵션에 따라 중복 호출 허용 시간 조절 가능)
  • 무한 스크롤
  • 비동기 과정을 선언적으로 관리할 수 있다
  • react hook과 사용하는 구조가 비슷하다.
  • 불필요한 코드 감소
  • API 요청 수행을 위한 규격화 된 방식 제공
  • 사용자 경험 향상을 위한 다양한 기능

 

사용법

 

설치법

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


예제

 

// 공식문서에서 나온 코드 살펴보기.
// App.js

import {
  QueryClient,
  QueryClientProvider,
  useQuery,
  
  // QueryClient, QueryClientProvder, useQuery를 불러와 사용하고 있는 것을 알 수 있어요.
} from '@tanstack/react-query'

const queryClient = new QueryClient() // QueryClient 인스턴스 생성 

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
    // App의 루트를 감싸주고 queryClient 객체를 전달한다. 
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isLoading, error, data } = useQuery({ 
  // useQuery로 API를 호출하고 isLoading, error, data를 받아올 수 있다. 
    queryKey: ['repoData'], // 쿼리 결과를 저장하고 캐시하는데 사용한다.
    queryFn: () =>
      fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
        (res) => res.json(),
      ),
    // api 요청을 수행하고 결과를 반환한다.
    //쿼리 데이터를 가져오는 방법을 정의하므로 fetch나 axios같은 함수를 사용한다. 
  }, {staleTime : 1000 * 60 * 10})
  
  // 지금은 첫 번째 인자 queryKey:['고유한 이름'], 두 번째 인자 queryFn: 함수로 지정 되어 있는데
  // queryKey, queryFn key를 생략 후 value만 적어줘도 된다.
  // ex) useQuery({['고유한 이름'], 함수})
  // 세 번째 인자 부터는 옵션으로, 현재는 설정한 staleTime 옵션으로 신선도를 10분간 유지하여 캐시된 데이터를 사용하게 한다.
  

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
    </div>
  )
}



useQuery가 리턴하는 객체를 공식문서에서 확인하기

 

useQuery | TanStack Query Docs

const { data,

tanstack.com

 

 

Query Keys

TanStack Query는 Query Key를 기반으로 캐싱을 관리해줍니다. 위의 예시에서 본 것과 같이 쿼리 키는 배열이어야 합니다. 단일 문자열이 포함된 간단한 배열부터 여러 문자열과 중첩된 객체가 포함된 복잡한 배열까지 다양할 수 있습니다. 

 

// A list of todos
useQuery({ queryKey: ['todos'], ... })

// Something else, whatever!
useQuery({ queryKey: ['something', 'special'], ... })

배열의 첫 번째가 'something'이고 두 번째가 'special이 아닌' 다른 'example' 일 경우 서로 다른 캐시를 사용하게 됩니다. 그래서 원하는 조건대로 사용할 수 있습니다. 

 

// An individual todo
// 특정 할 일 'todo'를 쿼리하고 5는 할 일의 고유한 아이디
useQuery({ queryKey: ['todo', 5], ... })

// An individual todo in a "preview" format
// 특정 할 일 'todo'를 쿼리하지만 preview: true를 추가하여 미리보기 형식의 데이터 요청
useQuery({ queryKey: ['todo', 5, { preview: true }], ...})

// A list of todos that are "done"
// 'todos'에서 타입이 'done'인 목록을 쿼리한다. 쿼리에 추가 매개변수를 전달하여 
{type: 'done'}만 필터링 하라는 것을 나타낸다. 
useQuery({ queryKey: ['todos', { type: 'done' }], ... })

 

이렇게 Query Key의 배열에 여러 조건을 추가해서 넣으면 데이터를 요청할 때 다양한 조건으로 사용할 수 있습니다

 

const { isLoading, error, data } = useQuery(['todos', {type='done'}], async() => {
 return fetch(`${type === 'done' ? 'done_' : '' }data.json`).then((res) => res.json());
 // type이 done일 경우 done_data.json을 가져온다.
});

 

 

참고하면 좋은 영상 소개



카카오 테크 - 눈에 보이지 않는 개선: My구독의 Redux에서 React-Query 전환 경험 공유 / if(kakao)2022

 

우아한 테크 -  [LIVE] React Query와 상태관리 :: 2월 우아한테크세미나

 

 

 

카카오 테크, 우아한 테크,  경환님 깃허브 (성을 모르겠네요 ㅠ.ㅠ.. 링크 참고!) 를 참고하였습니다.
 

카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유 | 카카오페이 기술 블로그

카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유에 대해 설명합니다. 이 글은 연작 중 1편에 해당합니다. 1편: 카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유, 2편: React Que

tech.kakaopay.com

 

react-query 개념 및 정리

react-query 개념 및 정리, react, react16, hook, useState, useRef, useMemo, useEffect, useReducer, useCallback, useQuery 동기적으로 실행

kyounghwan01.github.io

 

profile

드림오구

@드림오구