FrontEnd/Vue

[Vue-Query] useMutation

Grace 2023. 4. 20. 16:25

첫 페이지에서 간단하게 mutation을 사용하는 방법에 대해서 설명했었습니다. https://metadataplanning.atlassian.net/wiki/spaces/data/pages/105447542
먼저 첫 페이지에서 설명한 것 처럼 axios apis(axios를 통해 백엔드에 put, post, patch, delete 요청을 보내는 함수)가 작성되었다는 전제로 설명드립니다.

데이터 내보내기

import { useMuataion } from '@tanstack/vue-query'

const { mutate } = useMutation(createTodo);

기본적으로 데이터를 내보내기 위해서는 위와 같이 작성합니다.

이후 작성된 값을 통해 Todo를 만들려면 onClickCreate 함수가 실행되겠죠?

import { useMuataion } from '@tanstack/vue-query'
import { reactive } from 'vue'

const { mutate } = useMutation(createTodo);

const inputs = reactive({
  title: '',
  content: ''
})

const onClickCreate = () => {
  const { title, content } = inputs
  
  // 제목과 컨텐츠 검증 로직
  ...
  mutate({...inputs}, { // 투두 작성을 위해 파라미터를 넘겨주고 성공과 실패 로직 작성
    onSuccess: () => console.log("작성완료!!!"),
    onError: () => console.log("작성실패!!!"),
    onSettled: () => console.log("아무튼 실행!!!")
  })
}

여기서 onSettled는 useQuery에서도 사용할 수 있는 함수입니다. 요청이 성공하든 실패하든 아무튼 실행되는 함수입니다. 기본적으로 mutation을 사용하는 로직은 이게 전부입니다. 간단하죠?
하지만 우리는 작성하는 컴포넌트(View)를 재사용해서 update 로직까지 함께 작성해주고자 합니다. 이 때에는 mutate를 여러 개 작성해야 할텐데 어떻게 해야 할까요?

import { useMuataion } from '@tanstack/vue-query'

const { mutate: mutateCreateTodo } = useMutation(createTodo);
/* 이렇게도 가능! 
  const { mutate } = useMutation(createTodo); */
const { mutate: mutateUpdateTodo } = useMutation(updateTodo)

이런 경우에는 이런 식으로 mutate 각각에 이름을 작성해 줄 수 있습니다. createTodo에는 이름을 할당하지 않고 update에는 할당하지 않을 수도 있습니다.

중요한 것은 두 가지의 mutation을 분기해줘야 한다는 것입니다.

데이터 요청 상태

const { mutate,
        data, error,
        isLoading, isSuccess, isError, isPaused,
        status,
        failureCount
      } = useMutation(createTodo);

useMutation에서도 데이터 요청에 대한 다양한 상태를 전달 받을 수 있습니다.

  • data: 요청을 하고 성공했을 경우 전달받는 응답 값이 전달됩니다.
  • error: 요청을 하고 실패했을 경우 전달받는 에러 값이 전달됩니다.
  • isLoading / isSuccess / isError / isPaused : 각각 요청 후 로딩 중일 때, 성공했을 때, 실패했을 때, 중지 됐을 때를 불린(true/false) 값으로 전달 받습니다.
  • status: 위의 값들을 ‘loading’, ‘success’, ‘error’ 등의 string 값으로 전달 받습니다.
  • failureCount: 보통은 한 번에 요청이 실패하지만, retry 같은 실패 시 재요청을 보내겠다는 설정을 해준다면 요청 후 실패한 경우 실패 횟수를 리턴합니다. 성공하면 0으로 리셋됩니다.

데이터 변경 후 쿼리 재조회

데이터를 잘 요청했는데 이번에는 데이터를 요청하고나서 우리가 쿼리를 사용해 불러왔던 데이터는 다시 조회해서 보여주고 싶습니다. (예를 들어, 리스트에서 아이템 삭제 요청을 보내고 성공적으로 삭제 되었을 경우 리스트 최신화)

import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'

const queryClient = useQueryClient()
const { data } = useQuery('todoList', getTodos)
const { mutate } = useMutation(deleteTodo)

const onClickDelete = (id) => {
    mutate(id, {
      onSuccess: () => {
        queryClient.invalidateQueries("todoList");
      },
    });
};

현재 페이지에서 조회되고 있는 리스트는 data이고 쿼리의 키는 ‘todoList’입니다. 우리는 onClickDelete를 통해 해당 아이템을 삭제했기 때문에 성공했을 경우에 리스트를 최신화 해야합니다. 때문에 onSuccess 함수에서 queryClient를 불러와 invalidateQueries를 활용해 해당 키의 쿼리를 무효화하고 무효화된 쿼리는 데이터를 재요청(refetch)하기 때문에 리스트가 최신화됩니다.

'FrontEnd > Vue' 카테고리의 다른 글

[Vue] requestAnimationFrame  (0) 2023.04.25
[Vue-Query] persistQueryClient  (0) 2023.04.24
[Vue-Query] useQuery  (0) 2023.04.20
[Vue-Query] @tanstack/vue-query  (0) 2023.04.20
[Vue3] v-model props  (0) 2023.04.20