[React Query] 리액트 쿼리 useMutation 기본 편

김효선·2022년 3월 30일
66

React Query 사용기

목록 보기
3/5

너무나 오랜만에 쓰는 블로그....ㅠ.ㅠ

useMutation

  • useQuery 와 다르게 mutation은 데이터를 생성 / 업데이트 / 삭제 할 때 사용 된다.
  • 내가 리액트 쿼리를 좋아하는 이유 중 큰 비중을 차지하는 queryClient 의 invalidateQueries 메소드 및 setQueryData 메소드랑 같이 사용하면 최고의 효율을 낼 수 있다 너어무 좋다
  • mutation 의 성공을 바라며 미리 UI부터 변화시켜주는 optimistic update 기능도 사용자에게 정말 좋은 경험을 제공할 수 있다.
  • 전에 useQuery 편 처럼 useMutation 을 커스텀 훅으로 만드는 내용까지 시리즈로 모두 기록할 예정 !
import { useMutation } from "react-query";
// 더 많은 return 값들이 있다. 
const { data, isLoading, mutate, mutateAsync } = useMutation(mutationFn, options);

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

Options

mutationFn (variables: TVariables) => Promise<TData>

  • Required
  • 비동기 작업을 수행하고 프로미스를 반환하는 함수이다. (쉽게 말해 api 요청하는 함수)
  • variables 는 mutate가 전달하는 객체이다.

onMutate: (variables: TVariables) => Promise<TContext | void> | TContext | void

  • onMutate 는 mutation 함수가 실행되기 전에 실행되고 mutation 함수가 받을 동일한 변수가 전달된다.
  • optimistic update 사용 시 유용한 함수이다.

onSuccess: (data: TData, variables: TVariables, context?: TContext) => Promise<unknown> | voi

  • onSuccess 는 mutation 이 성공하고 결과를 전달할 때 실행된다.

onError: (err: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void

  • onError 는 mutation 이 error 를 만났을 때 실행된다.

onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void

  • onSettled 는 mutation 이 성공해서 성공한 데이터 또는 error가 전달될 때 실행된다. (성공하든 실패하든 아무튼 결과가 전달된다)

Returns

mutate: (variables: TVariables, { onSuccess, onSettled, onError }) => void

  • mutate 를 호출해서 mutation 을 실행시킬 수 있다.
  • variables 는 mutationFn 에 전달하는 객체이다.
  • onSuccess, onSettled, onError 는 useMutation option에 설명한 것과 동일하다.

    ❗️ 다만, 두 곳에서 추가 콜백(onSuccess, onSettled, onError)을 실행할 경우 useMutation 의 추가 콜백 -> mutate 의 추가 콜백 순서로 실행된다.
    컴포넌트가 unmount 되면 추가 콜백이 실행되지 않는다 주의!!!

useMutation(addTodo, {
   onSuccess: (data, variables, context) => {
     // I will fire first
   },
   onError: (error, variables, context) => {
     // I will fire first
   },
   onSettled: (data, error, variables, context) => {
     // I will fire first
   },
  });

mutate(todo, {
   onSuccess: (data, variables, context) => {
     // I will fire second!
   },
   onError: (error, variables, context) => {
     // I will fire second!
   },
   onSettled: (data, error, variables, context) => {
     // I will fire second!
   },
});

mutateAsync: (variables: TVariables, { onSuccess, onSettled, onError }) => Promise<TData>

  • mutate 와 같으나 promise 를 반환한다!

>> 더 많은 option과 return 값들은 이 링크에서 <<


Example

import { useMutation } from "react-query";
import axios from 'axios';

interface TodoType {
  id: number;
  todo: string;
}

const addTodo = async (newTodo: TodoType): Promise<TodoType> => {
  const { data } = await axios.post<TodoType>(`/todos`, newTodo);
  return data;
};

// api 요청하는 함수(addTodo) 를 작성하지 않았을 경우
const { mutate, isLoading, isError, error, isSuccess } = useMutation(newTodo => {
  return axios.post<TodoType>('/todos', newTodo);
});
// api 요청하는 함수(addTodo) 를 작성했을 경우
const { mutate, isLoading, isError, error, isSuccess } = useMutation(addTodo);

export default function App() {
  return (
    <div>
      {
        isLoading ? (
          'Adding todo...'
        ) : (
        <>
          {isError && <p>error: {error.message}</p>}
            
          {isSuccess && <p>Todo added!</p>}
            
          <button
            onClick={() => {
              mutate({ id: 1, todo: 'useMutation 블로그 작성하기' })
            }}
          >
               작성 완료
          </button>
        </>
        )
      }
    </div>
  );
}
profile
차근차근 나아가는 주니어 프론트엔드 개발자

0개의 댓글