react-query useMutation()

RumbleBi·2023년 2월 23일
0

react-query

목록 보기
6/6
post-thumbnail

useMutation()

useMutation은 데이터의 수정, 삭제를 서버에 요청하는 메서드이다.
이 블로그 포스트의 openAPI는 요청을 보내도 데이터가 수정되거나 하지 않지만 응답값은 잘 나오니 변경된 것이라고 가정하에 작성한다.

delete

// PostDetail.jsx

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

async function fetchComments(postId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/comments?postId=${postId}`);
  return response.json();
}

async function deletePost(postId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/postId/${postId}`, {
    method: "DELETE",
  });
  return response.json();
}

async function updatePost(postId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/postId/${postId}`, {
    method: "PATCH",
    data: { title: "REACT QUERY FOREVER!!!!" },
  });
  return response.json();
}

export function PostDetail({ post }) {
  const { data, isLoading, isError, error } = useQuery(["fetchComments", post.id], () =>
    fetchComments(post.id)
  );

  const deleteMutation = useMutation((postId) => deletePost(postId));

  if (isLoading) return <h2>Loading...</h2>;
  if (isError)
    return (
      <>
        <h2>Error!</h2>
        <p>{error.toString()}</p>
      </>
    );
  return (
    <>
      <h3 style={{ color: "blue" }}>{post.title}</h3>
      <button onClick={() => deleteMutation.mutate(post.id)}>Delete</button>
      {deleteMutation.isError && <p style={{ color: "red" }}>Error deleting the post</p>}
      {deleteMutation.isLoading && <p style={{ color: "yellow" }}>Deleting the post</p>}
      {deleteMutation.isSuccess && <p style={{ color: "green" }}>Deleted the post</p>}
      <button>Update title</button>
      <p>{post.body}</p>
      <h4>Comments</h4>
      {data.map((comment) => (
        <li key={comment.id}>
          {comment.email}: {comment.body}
        </li>
      ))}
    </>
  );
}

useMutation의 경우에는 queryKey가 필요하지 않고 바로 작동시킬 함수를 작성하면 된다. 여기서 useQuery와의 차이점이 있다.

const deleteMutation = useMutation((postId) => deletePost(postId));

useQuery는 인수(argument)로서 전달하는 쿼리 함수와는 달리 useMutation에서는 쿼리 함수 자체에서 인수를 받을 수 있다.

<button onClick={() => deleteMutation.mutate(post.id)}>Delete</button>

그래서 삭제 버튼을 누르면 실행시키는 함수에서도 post.id의 인수를 전달하면 위의 코드의 postId로 들어가게 되어 실행되는 것이다.

{deleteMutation.isError && <p style={{ color: "red" }}>Error deleting the post</p>}
      {deleteMutation.isLoading && <p style={{ color: "yellow" }}>Deleting the post</p>}
      {deleteMutation.isSuccess && <p style={{ color: "green" }}>Deleted the post</p>}

코드와 같이 mutation에 실패했을 경우의 isError, 진행중일 때의 isLoading, 성공했을때의 isSuccess 등의 추가적인 메서드들이 있다.

update

async function updatePost(postId) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/postId/${postId}`, {
    method: "PATCH",
    data: { title: "UPDATE SUCCESS" },
  });
  return response.json();
}

업데이트의 경우에는 메서드를 PATCH로 설정하고 data 객체 안에 title 을 변경하면된다. 예시에서는 하드코딩으로 설정했지만 input 입력값을 받은 데이터를 useState로 저장하여 설정할 수 있다.

const updateMutation = useMutation((postId) => updatePost(postId));

만약 useState를 사용한다면 updatePost함수에 두번째 인수에 넣어주고 하드코딩 된 부분을 수정해주면 변경될 것이다.

<button onClick={() => updateMutation.mutate(post.id)}>Update title</button>
      {updateMutation.isError && <p style={{ color: "red" }}>Error updating the post</p>}
      {updateMutation.isLoading && <p style={{ color: "yellow" }}>Updating the post</p>}
      {updateMutation.isSuccess && <p style={{ color: "green" }}>Updated the post</p>}

물론 똑같이 isError, isLoading, isSuccess 객체가 있으므로 동일하게 사용이 가능하다.

profile
기억보다는 기록하는 개발자

0개의 댓글