Tanstack Query

foresec·2024년 6월 3일

Project

목록 보기
6/11

Tanstack Query

react query였지만, v4부터 React를 포함한 Vue, Svelte등에서도 사용이 가능해지며 Tanstack Query로 이름이 변경되었다.

아래 글은 v5를 기준으로 작성되었다.

왜 쓰는걸까?

Data Fetching + 상태 관리에 도움을 줌
ex) 서버의 상태를 가져오고, 캐싱, 동기화, 비동기 업데이트에 유용함

기존의 상태 관리 라이브러리는 client 상태 작업에 적합하지만, 비동기 or 서버의 상태 작업에는 서버의 상태가 다르기때문에 적합하지 않다고 한다.
쉽게 말하면 기존에 서버에서 받아온 데이터를 어떻게 처리하고, 또 데이터를 언제 다시 가져와야할지 등을 관리할 수 있다.

공식문서에도 나와있는 Quick Start를 살펴보면

1. 설치 후 Provider

import {
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'

// Create a client
const queryClient = new QueryClient()

function App() {
  return (
    // Provide the client to your App
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

먼저, queryClient 인스턴스를 제공하기 위해 provider를 최상단에서 감싸줘야한다.
이로서 여기에 속한 하위 컴포넌트에서 useQuery, useMutation과 같은 hook을 사용할 때 queryClient에 접근할 수 있다.

2. useQuery, useMutation +

import {
  useQuery,
  useMutation,
  useQueryClient,
} from '@tanstack/react-query'
import { getTodos, postTodo } from '../my-api'

function Todos() {
  // Access the client
  const queryClient = useQueryClient()

  // Queries
  const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })

  // Mutations
  const mutation = useMutation({
    mutationFn: postTodo,
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
  })

  return (
    <div>
      <ul>{query.data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul>

      <button
        onClick={() => {
          mutation.mutate({
            id: Date.now(),
            title: 'Do Laundry',
          })
        }}
      >
        Add Todo
      </button>
    </div>
  )
}

render(<App />, document.getElementById('root'))

useQuery

주로 HTTP GET 요청과 같이 서버 데이터를 가져올 때 쓰이는 훅

queryKey, queryFn이 필수적으로 선언되어야 하며 Option은 선택사항

const query = useQuery(queryKey, queryFn, Option)
// 실제 사용 예시
const { data, error } = useQuery({ queryKey: ['todos'], queryFn: getTodos })
  • queryKey는 고유한 값이며, 한번의 데이터 요청 후 해당 데이터가 캐싱되었고 같은 queryKey를 가졌을 때 캐시된 데이터가 공유된다.
  • queryFn는 쿼리가 데이터를 요청하는데 사용하는 함수로 데이터를 가져오는 비동기 작업을 수행한다(Promise를 반환).

그 외 옵션으로는

  • staleTime : 데이터가 만료되어 새로운 데이터로 갱신되어야 하는 밀리세컨드 시간(데이터의 신선도)
  • gcTime(구 cacheTime) : 쿼리로 받아 온 데이터가 메모리에 비활성화된 상태로 유지되는 시간, 시간을 경과할 경우 가비지 컬렉션 프로세스에 의해 삭제된다.
  • retry : 쿼리 실행 중 실패할 경우 재시도할지 여부
  • refetchInterval : 지정된 시간마다 쿼리를 다시 실행할지 여부
  • refetchIntervalInBackground : 브라우저 창이 백그라운드에 있을 때도 지정된 시간 간격마다 쿼리를 다시 실행할지 여부
  • refetchOnMount : 컴포넌트가 마운트 될 때마다 쿼리를 다시 실행할지 여부
  • refetchOnWindwoFocus : 브라우저 창이 포커스를 받을 때마다 쿼리를 다시 실행할지 여부
  • enabled : 쿼리가 자동으로 실행될지 여부 -> 의존적으로 실행할지 결정가능

useQuery를 사용함으로서 받아올 수 있는 대표적인 속성으로

  • data : 쿼리에서 가져온 데이터(반환 성공) - > 말그대로 데이터
  • error : 쿼리 실행 중 발생한 오류 -> 오류처리 및 메시지 표시 가능
  • isLoading : 데이터를 가져오는 중에 대한 여부 -> UI 로딩 스피너
  • isError : 쿼리 실행 중 오류가 발생했는지 여부 -> UI 처리 관련
  • isSuccess : 쿼리가 성공적으로 완료되었는지 여부 -> UI 처리 관련
  • refetch : 쿼리를 다시 실행하는 함수 -> 데이터를 다시 가져올 수 있음

등이 있는데, 이외에도 많지만 전부 한번에 알아보기엔 너무 많으므로 필요할 때 찾아서 쓰는게 나을 듯 하다.

useMutation

주로 HTTP POST, PUT, DELETE 등 변경을 일으킬때 쓰이는 훅

mutationFn이 필수적으로 선언되어야 하며 option은 선택사항

const {mutate, isPending, isError, isSuccess } = useMutation({ mutationFn, option });

mutate(variables, {
  onError,
  onSettled,
  onSuccess,
})

const mutation = useMutation({
    mutationFn: postTodo,
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
  })

mutationFn은 비동기 작업을 수행하고(변경) 그 결과를 반환함

그 외 옵션으로는

  • onSuccess : mutation이 성공적으로 실행된 후에 실행되는 콜백 함수
  • onError : mutation이 오류를 만났을 때 실행되는 콜백 함수
  • onSettled : mutation이 완료되거나 오류가 발생했을 때 실행되는 함수

또한, mutate함수를 통해 받아온 결과에 따라 원하는 작업을 트리거 가능함

  • variables : 변수, 이를 활용하여 뮤테이션 실행

useMutation 또한 옵션이나 반환되는 값과 콜백함수가 많으므로 필요한 사항을 필요할 때 찾아서 써야할 듯하다

useQueryClient

쿼리 클라이언트 인스턴스를 반환하며, 쿼리와 캐시 관련 작업에 쓰일 수 있다.

profile
왼쪽 태그보다 시리즈 위주로 구분

0개의 댓글