본문으로 건너뛰기

뮤테이션 응답을 통한 업데이트

서버에서 객체를 업데이트하는 뮤테이션을 처리할 때는 새 객체가 뮤테이션 응답으로 자동 반환되는 경우가 많습니다. 해당 항목에 관한 쿼리를 다시 가져와 이미 보유한 데이터를 위해 네트워크 호출을 낭비하는 대신, 뮤테이션 함수가 반환한 객체를 활용하고 Query Client의 setQueryData 메서드를 사용하여 기존 쿼리를 새 데이터로 즉시 업데이트할 수 있습니다:

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,
})

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)
},
})
}

불변성

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,
)