useMutation

모찌모찌·2024년 5월 9일

리액트쿼리

목록 보기
4/7

✅ useMutation

서버의 데이터를 변경할 때 사용합니다.
HTTP POST, PUT, DELETE 요청을 사용할 수 있습니다.

mutationFn은 queryFn처럼 Promise를 리턴하는 비동기 함수입니다.
파라미터를 전달받을 수 있습니다.

mutationFn 파라미터는 useMutation의 리턴값인 mutate 함수의 인자로 전달됩니다.

🔥mutationFn에서는 어떻게 동작할지 정의만 하고, mutate 함수를 통해 나중에 실행되는 것입니다

✍🏻 사용법

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

//뮤테이션 했을 때 실행할 함수 등록
const uploadPostMutation = useMutation({
  mutationFn: (newPost) => uploadPost(newPost),
  },
});

//정의해 둔 mutation이 실행되도록 mutate() 함수를 불러준다.
const handleUploadPost = (newPost) => {
  uploadPostMutation.mutate(newPost, {
    onSuccess: () => {
      toast('포스트가 성공적으로 업로드 되었습니다!');
    },
  });
};

useMutation()훅을 이용해 새로운 데이터를 추가해 보았습니다. 그런데 캐시에 있는 데이터가 업데이트되지 않아, 새로운 데이터를 확인하려면 새로고침을 해 줬어야 했죠.

✅ invalidateQueries() 함수

쿼리 클라이언트의 invalidateQueries()라는 함수를 사용하면 업로드가 끝난 이후에 자동으로 refetch를 하도록 설정할 수 있습니다.

쿼리를 invalidate하면 해당 쿼리를 통해 받아 온 데이터를 stale time이 지났는지 아닌지에 상관없이 무조건 stale 상태로 만들고, 해당 데이터를 백그라운드에서 refetch하게 됩니다.
(특정 API 호출 후, 데이터를 갱신하고 싶을 때 사용할 수 있습니다.)

사용법

쿼리 클라이언트는 useQueryClient() 훅을 사용해서 가져올 수 있고요, 원하는 시점에 queryClient.invalidateQueries() 함수를 실행하면 됩니다.

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

const queryClient = useQueryClient();

// ...

queryClient.invalidateQueries();

✅ useMutation() 함수의 콜백 옵션

언제 쿼리를 invalidate해야 할까요? 뮤테이션 객체에는 onMutate, onSuccess, onError, onSettled와 같은 주요 옵션들이 있어서 뮤테이션 사이클에 따라 적절한 동작을 추가할 수 있습니다.
( mutate()함수의 콜백옵션도 위와 같다.)

우리는 onSuccess, 즉 뮤테이션이 성공한 시점에 ['post'] 쿼리를 invalidate해 주는 함수를 콜백으로 등록해 주면 되겠죠. 아래 코드를 추가하면 포스트를 업로드하자마자 업로드된 포스트까지 화면에 잘 보이는 것을 확인할 수 있습니다.


const queryClient = useQueryClient();

// ...

const uploadPostMutation = useMutation({
  mutationFn: (newPost) => uploadPost(newPost),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['posts'] });
  },
});

🔥 주의점

useMutation()에 등록된 콜백 함수들은 컴포넌트가 언마운트되더라도 실행이 되지만, mutate()의 콜백 함수들은 만약 뮤테이션이 끝나기 전에 해당 컴포넌트가 언마운트되면 실행되지 않는 특징을 가지고 있다.

따라서 query invalidation과 같이 뮤테이션 과정에서 꼭 필요한 로직은 useMutation()을 통해 등록하고, 그 외에 다른 페이지로 리다이렉트한다든가, 혹은 결과를 토스트로 띄워주는 것과 같이 해당 컴포넌트에 종속적인 로직은 mutate()통해 등록해 주면 됩니다.

...

const uploadPostMutation = useMutation({
  mutationFn: (newPost) => uploadPost(newPost),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: ['posts'] });
  },
});

const handleUploadPost = (newPost) => {
  uploadPostMutation.mutate(newPost, {
    onSuccess: () => {
      toast('포스트가 성공적으로 업로드 되었습니다!');
    },
  });
};
profile
꼬꼬마 개발자 지망생

0개의 댓글