TanStack Query (React Query) 공식문서 정복하기 (2)

2024. 6. 11. 15:10· 리액트
목차
  1. Queries
  2. useQuery 사용법 
  3. useQuery 결과 상태 
  4. Mutations 
  5. useMutaion 결과 상태
  6. useMutaion 사용법 

오늘은 지난 포스트에서 설명했듯 useQuery와 useMutation에 대해 작성해 볼 것이다.

 

Queries

쿼리는 고유 키와 연결된 비동기 데이터 소스에 대한 선언적 의존이다. 쿼리는 서버에서 데이터를 가져오기 위해 Promise 기반 메서드(예: GET 및 POST)를 사용한다. 데이터를 수정하는 메서드에는 Mutations를 사용하는 것이 좋다.

 

서버에서 데이터를 가져올 때 -> useQuery 
데이터를 수정할 때 -> useMutaion 

 

useQuery 사용법 

queryKey : 쿼리의 고유 키 , 캐시를 관리하기 위한 키 값으로 배열 형태로 사용 

queryFn : promise 를 반환하는 함수 

 

import { useQuery } from '@tanstack/react-query'

function App() {
  const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
}

 

제공된 고유 키는 내부적으로 재패칭, 캐싱, 쿼리 공유 등에 사용된다. 

useQuery가 반환하는 쿼리 결과 객체는 쿼리에 필요한 모든 정보를 포함한다. (데이터, 에러 , isLoading, isFetching  ... ) 

 

우리가 흔히 데이터를 요청할 때 데이터를 요청하고 기다린 후 데이터가 성공적으로 요청되거나 , 에러가 발생하거나 하는 상태가 존재한다. useQuery를 사용하면 이러한 상태들을 관리하는데 용이하다. 

 

useQuery 결과 상태 

  1. isPending 또는 status === 'pending' - 아직 데이터가 없음
  2. isError 또는 status === 'error' - 오류 발생
  3. isSuccess 또는 status === 'success' - 성공적으로 데이터가 있음

또한 각 상태에 따라 추가 정보를 얻을 수 있다. 

  1. isFetching - 어떤 상태에서도 쿼리가 패칭 중일 때
  2. error - isError 상태일 때 오류 정보
  3. data - isSuccess 상태일 때 데이터
function Todos() {
  const { isPending, isError, data, error } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  });

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

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

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

 

function Todos() {
  const { status, data, error } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  });

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

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

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

 

이런식으로 사용하게 되면 데이터의 상태에 따라 완전히 데이터를 받아오기 전 사용자에게 로딩창을 띄워주거나 에러 발생 시 에러메세지를 띄워줄 수 있다. 

 

또한 추가적으로 status 필드 외에  fetchStatus 속성도 있다.

  • fetchStatus === 'fetching' - 현재 패칭 중
  • fetchStatus === 'paused' - 패칭이 필요하지만 중단됨 (네트워크 모드 가이드 참조)
  • fetchStatus === 'idle' - 현재 아무 것도 하지 않음

왜 두 가지 상태가 필요한가?

백그라운드 재패칭과 stale-while-revalidate 로직은 모든 상태와 fetchStatus 조합을 가능하게 한다.

예를 들어

  • 성공 상태의 쿼리는 보통 idle fetchStatus에 있지만, 백그라운드 재패칭 중이라면 fetching일 수도 있다.
  • 데이터가 없는 쿼리는 보통 pending status와 fetching fetchStatus에 있지만, 네트워크 연결이 없으면 paused일 수도 있다.

따라서 쿼리는 실제로 데이터를 패칭하지 않고도 pending 상태일 수 있다. 

  • status는 데이터에 대한 정보를 제공한다 ->  데이터가 있는지 여부
  • fetchStatus는 queryFn에 대한 정보를 제공한다 -> 실행 중인지 여부

 


Mutations 

queries와 달리 mutations는 데이터를 생성/업데이트/삭제하거나 서버 측 효과를 수행하는 데 사용된다. (CUD에 해당하는 기능)

mutations는 쿼리키는 필요하지 않고 queryFn만 사용한다. 

import { useMutation } from '@tanstack/react-query';
import axios from 'axios';

function App() {
  const mutation = useMutation({
    mutationFn: (newTodo) => {
      return axios.post('/todos', newTodo);
    },
  });

  return (
    <div>
      {mutation.isPending ? (
        'Adding todo...'
      ) : (
        <>
          {mutation.isError ? (
            <div>An error occurred: {mutation.error.message}</div>
          ) : null}

          {mutation.isSuccess ? <div>Todo added!</div> : null}

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

 

useMutaion 결과 상태

  1. isIdle 또는 status === 'idle' - 현재 대기 중이거나 초기 상태
  2. isPending 또는 status === 'pending' - 현재 실행 중
  3. isError 또는 status === 'error' - 오류 발생
  4. isSuccess 또는 status === 'success' - 성공적으로 완료되어 데이터가 있음

상태에 따른 추가 정보:

  1. error - 오류 상태일 때 오류 정보 제공
  2. data - 성공 상태일 때 데이터 제공

useMutaion 사용법 

기본적인 사용방법은 위에서 설명했고 아래는 특별히 주의할 점에 대해 작성해볼 것이다. 

 

1. mutate 함수는 비동기 함수이므로 React 16 및 이전 버전 의 이벤트 콜백에서 직접 사용할 수 없다 .onSubmit 에서 이벤트에 액세스해야 하는 경우 mutate를 다른 함수로 래핑해야 합니다 . 이는 React 이벤트 풀링 때문

// This will not work in React 16 and earlier
const CreateTodo = () => {
  const mutation = useMutation({
    mutationFn: (event) => {
      event.preventDefault()
      return fetch('/api', new FormData(event.target))
    },
  })

  return <form onSubmit={mutation.mutate}>...</form>
}

// This will work
const CreateTodo = () => {
  const mutation = useMutation({
    mutationFn: (formData) => {
      return fetch('/api', formData)
    },
  })
  const onSubmit = (event) => {
    event.preventDefault()
    mutation.mutate(new FormData(event.target))
  }

  return <form onSubmit={onSubmit}>...</form>
}

 

2. Mutation 상태 재설정 

요청의 오류나 데이터를 지워야 할 때는 reset 함수를 사용하면 된다. 

const CreateTodo = () => {
  const [title, setTitle] = useState('')
  const mutation = useMutation({ mutationFn: createTodo })

  const onCreateTodo = (e) => {
    e.preventDefault()
    mutation.mutate({ title })
  }

  return (
    <form onSubmit={onCreateTodo}>
      {mutation.error && (
        <h5 onClick={() => mutation.reset()}>{mutation.error}</h5>
      )}
      <input
        type="text"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <br />
      <button type="submit">Create Todo</button>
    </form>
  )
}

 

3. Mutation 재시도 

TanStack Query는 mutation 오류 시 재시도하지 않지만 retry 옵션으로 가능하게 할 수 있다. 

const mutation = useMutation({
  mutationFn: addTodo,
  retry: 3,
});

retry : 3 을 설정해둔단면 동작 실패 시 3번 재시도 한다는 의미이다. 

 

4. Promise 반환 

성공 시 해결되거나 오류가 발생하는 promise을 얻으려면 mutate  대신 mutateAsync를 사용하면 된다.  

const mutation = useMutation({ mutationFn: addTodo })

try {
  const todo = await mutation.mutateAsync(todo)
  console.log(todo)
} catch (error) {
  console.error(error)
} finally {
  console.log('done')
}

 

 

오늘은 이렇게 useQuery와 useMutation의 차이점과 사용방법에 대해 알아보았다. 

각 훅들이 제공하는 유용한 옵션들도 있으니 함께 알아보고 사용하면 좋을 것 같다 !! 

https://tanstack.com/query/latest/docs/framework/react/reference/useQuery

 

useQuery | TanStack Query React Docs

Does this replace [Redux, MobX, etc]? react

tanstack.com

https://tanstack.com/query/latest/docs/framework/react/reference/useMutation

 

useMutation | TanStack Query React Docs

Does this replace [Redux, MobX, etc]? react

tanstack.com

 

 

다음 포스트에서는 진행중인 프로젝트에 리액트 쿼리를 적용한 결과에 대해 작성해 볼 것이다. 

'리액트' 카테고리의 다른 글

드래그 앤 드롭 이해하기: React DnD를 활용한 칸반보드 드래그 앤 드롭 기능 구현하기 (RTK + React DnD )  (0) 2025.02.14
TanStack Query (React Query) 공식문서 정복하기 (1)  (1) 2024.06.10
[리액트] 웹 배포 시 다크모드가 설정되어 CSS가 깨지는 경우엔 ?  (0) 2024.02.21
솔로프로젝트 - MaMaMeMo (아이디어 기획 및 디자인)  (0) 2023.09.11
[블로깅 챌린지] 리액트로 간단한 컴포넌트 구현하기  (0) 2023.05.03
  1. Queries
  2. useQuery 사용법 
  3. useQuery 결과 상태 
  4. Mutations 
  5. useMutaion 결과 상태
  6. useMutaion 사용법 
'리액트' 카테고리의 다른 글
  • 드래그 앤 드롭 이해하기: React DnD를 활용한 칸반보드 드래그 앤 드롭 기능 구현하기 (RTK + React DnD )
  • TanStack Query (React Query) 공식문서 정복하기 (1)
  • [리액트] 웹 배포 시 다크모드가 설정되어 CSS가 깨지는 경우엔 ?
  • 솔로프로젝트 - MaMaMeMo (아이디어 기획 및 디자인)
배트리버
배트리버
🐾 사람 좋아, 개발 좋아 🐾 궁금한 건 끝까지 파고들고, 배운 건 즐겁게 나누는 개발자의 놀이터
배트리버
리트리버의 개발 놀이터
배트리버
전체
오늘
어제
  • 분류 전체보기
    • 네트워크
    • 기초 셋팅
    • 오늘의 일기
    • 리액트
    • 코테 준비
      • 프로그래머스
      • 백준
    • 코드스테이츠44기 프론트엔드
    • HTML-CSS-JavaScript
      • HTML
      • CSS
      • JavaScript
    • 자료구조&알고리즘
    • TypeScript
    • Git
    • Tip
    • 프로젝트
    • Next.js
    • 트러블슈팅

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 리액트 상태관리
  • BFS
  • 코드스테이츠 회고록
  • 코드스테이츠 블로깅
  • 코드스테이츠 프론트엔드
  • 프로그래머스
  • 자바스크립트
  • 코드스테이츠
  • 티스토리챌린지
  • 코드스테이츠 44기
  • 오블완
  • 리액트쿼리
  • 자바스크립트 비동기
  • KPT 회고
  • 리액트
  • 프로젝트 회고
  • 탄스택쿼리
  • 네트워크
  • 타입스크립트문법
  • 코드스테이츠 44기 프론트엔드

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
배트리버
TanStack Query (React Query) 공식문서 정복하기 (2)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.