[TanStakQuery] Updates from Mutation Responses

Jeris·2023년 5월 22일
0

서버에서 객체를 업데이트하는 mutation을 처리할 때, 일반적으로 mutation response로 새 객체가 자동으로 리턴되는 것이 일반적입니다. 해당 항목에 대한 쿼리를 refeching하고 이미 가지고 있는 데이터에 대한 네트워크 호출을 낭비하는 대신, Query Client's setQueryData 메서드를 사용하여 mutation 함수가 리턴한 객체를 활용하고 기존 쿼리를 새 데이터로 즉시 업데이트할 수 있습니다:

const queryClient = useQueryClient()

const mutation = useMutation({
  mutationFn: editTodo,
  onSuccess: data => {
    queryClient.setQueryData(['todo', { id: 5 }], data)
  }
})

mutation.mutate({
  id: 5,
  name: 'Do the laundry',
})

// The query below will be updated with the response from the
// successful mutation
const { status, data, error } = useQuery({
  queryKey: ['todo', { id: 5 }],
  queryFn: fetchTodoById,
})

재사용 가능한 mutation에 onSuccess 로직을 연결하면 다음과 같은 커스텀 훅을 만들 수 있습니다:

const useMutateTodo = () => {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: editTodo,
    // Notice the second argument is the variables object that the `mutate` function receives
    onSuccess: (data, variables) => {
      queryClient.setQueryData(['todo', { id: variables.id }], data)
    },
  })
}

Immutability

setQueryData를 통한 업데이트는 변경 불가능한 방식으로 수행해야 합니다. 캐시에서 검색한 데이터를 제자리에서 변경하여 캐시에 직접 쓰려고 시도하지 마세요. 처음에는 작동할 수 있지만 그 과정에서 미묘한 버그가 발생할 수 있습니다.

queryClient.setQueryData(
  ['posts', { id }],
  (oldData) => {
    if (oldData) {
      // ❌ do not try this
      oldData.title = 'my new post title'
    }
    return oldData
  })

queryClient.setQueryData(
  ['posts', { id }],
  // ✅ this is the way
  (oldData) => oldData ? {
    ...oldData,
    title: 'my new post title'
  } : oldData
)

Reference

profile
job's done

0개의 댓글