전체 방문자
오늘
어제
  • 전체 글
    • HTML
    • CSS
    • Javascript
    • React
    • Typescript
    • Next.js
    • Webpack
    • Vue.js
    • Git & GitHub
    • Error
    • Study
    • 개발 일지✨

블로그 메뉴

  • 💡
  • ⚙️
hELLO · Designed By 정상우.
하루

Home

React

[React-Query] useMutation 사용하기

2022. 11. 26. 21:46

useMutation

import { useMutation } from "react-query";
const { data, isLoading, mutate } = useMutation(mutationFn, options);

useMutation hook은 인자로 2가지를 받는다. useQuery 처럼 key 값은 따로 없다.

  1. mutationFn: mutate를 위한 패치함수 (필수)
  2. options: 옵션 (선택)

mutationFn 함수로 POST, PUT, DELETE 및 각 요청에 필요한 인자들이 포함된다.

또한, options로 설정하는 값들, 그리고 반환되는 프로퍼티들은 아래와 같은 값들이 있다. (공식문서 참고) 

 

options

  • onMutate

mutation 전에 실행되는 함수로, 미리 렌더링 하고자 할 때 유용하다.

이 함수가 반환하는 값을 아래 함수들의 context로 사용가능.

(variables) => Promise<Context> | void
  • onSuccess

mutation 이 성공하고 결과를 전달할 때 실행

(data, variables, context?) => void
  • onError

mutation 이 실패했을 시 에러를 전달한다.

(error, variables, context?) => void
  • onSettled

mutation 의 성공/실패 여부와 상관없이 완료됐을 때 실행

(data, error, variables, context?) => void

이 외에도 mutationKey, retry, cacheTime 등 다양한 옵션이 존재한다.

 

returns

  • mutate

mutation 을 실행시키는 메서드로 가장 많이 쓰인다.

variables 매개변수가 mutationFn 으로 전달되며, 옵션의 메서드들은 위 Options 함수들과 동일하다.

* 단 두 곳 모두에서 콜백을 실행하면, Options 콜백 -> mutate 옵션의 콜백 순으로 실행된다.

(variables, { onSuccess, onError, onSettled }) => void
  • mutateAsync

mutate 결과를 Promise로 반환한다.

mutation 결과를 다루거나 비동기 연쇄로직이 필요한 경우 유용하나, catch() 로 에러 핸들링을 직접 해야한다는 유의점이 있다.

(variables, { onSuccess, onError, onSettled }) => Promise<Data>

이외 에도 status(idle, loading, error, success), data, isLoading, error, isError 등 다양한 값을 반환한다.

 

POST 요청

1. Hook 제작

// src/hooks/apis/useSuperHeroQuery.js

import { useMutation, useQuery, useQueryClient } from "react-query";
import axios from "axios";

const fetchAddSuperHero = (hero) => {
  return axios.post("http://localhost:4000/superheroes", hero)
}

export const useAddSuperHeroMutation = () => {
  return useMutation(fetchAddSuperHero) 
}
  • mutationFn인 fetchAddSuperHero() 함수를 만든다. axios.post를 반환하며, body에 값으로 담을 hero를 인자로 받는다. (이 hero 값은, 추후 useMutation() 의 mutate 메서드를 통해 전달)
  • useAddSuperHeroMutation() 훅을 제작한다. 이는, useMutation() 자체를 반환하며, 인자로 패치 함수와 옵션 등을 설정한다.

 

2. 적용

import { useState } from "react";
import { Link } from "react-router-dom";
import { useSuperHeroesQuery, useAddSuperHeroMutation } from "../hooks/apis/useSuperHeroesQuery";

export const RQSuperHeroesPage = () => {
  const [newHero, setNewHero] = useState({ name: "", alterEgo: "" });

  const { isLoading, data, isError, error, refetch } = useSuperHeroesQuery();

  // 1) useAddSuperHeroMutation() Hooks 가져오기
  const { mutate: addHero, isLoading2, isError2, error2 } = useAddSuperHeroMutation(newHero)

  // 2) mutate() 함수 실행부
  const handleClickAddButton = () => {
    addHero(newHero)
    setNewHero({ name: "", alterEgo: "" })
  }

  if (isLoading) return <h2>Loading...!!</h2>;

  if (isError) return <h2>{error.message}</h2>;

  return (
    <>
      <h2>React Query Super Heroes Page</h2>
      <div>
        <input
          value={newHero.name}
          onChange={(e) =>
            setNewHero((prev) => ({ ...prev, name: e.target.value }))
          }
          placeholder="name"
        />
        <input
          value={newHero.alterEgo}
          onChange={(e) =>
            setNewHero((prev) => ({ ...prev, alterEgo: e.target.value }))
          }
          placeholder="alterEgo"
        />
        <button onClick={handleClickAddButton}>Add Hero</button>
      </div>
      <button onClick={refetch}>refresh</button>
      {data?.data.map((hero) => (
        <div key={hero.name}>
          <Link to={`/rq-super-hero/${hero.id}`}>{hero.name}</Link>
        </div>
      ))}
    </>
  );
};
  1. useAddSuperHeroMutation 훅을 가져온다. useMutation() 이 반환하는 프로퍼티들을 사용할 수 있으며, 여기서 특히 mutate() 함수를 사용하는 것이 중요하다.
  2. mutate() 함수를 addHero 라는 네이밍으로 가져왔다. 이는, mutation을 실행하는 함수이며, newHero를 인자로 전달하면 이는 useAddSuperHeroMutation() 훅에서 useMutation()의 첫번째 인자인 mutationFn에 전달된다.
  3. button을 클릭했을 때, hadleClickAddButton 핸들러 함수가 실행된다. 이 때, 포함된 mutate() 함수 역시 실행될 것이다.

 

 


출처

- https://abangpa1ace.tistory.com/266

    'React' 카테고리의 다른 글
    • [React] Router
    • [React] 함수형 컴포넌트에서 데이터 전달
    • Redux와 Recoil 개념 정리
    • [React] React Query의 useQuery

    티스토리툴바