Updates from Mutation Responses
서버에서 객체를 업데이트하는 뮤테이션을 처리할 때, 새 객체가 뮤테이션 응답에서 자동으로 반환되는 것이 일반적입니다. 이미 가지고 있는 데이터에 대해 네트워크 호출을 낭비하는 대신, 뮤테이션 함수가 반환한 객체를 활용하여 기존 쿼리를 새 데이터로 즉시 업데이트할 수 있습니다. 이를 위해 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",
});
// 아래 쿼리는 성공적인 뮤테이션의 응답으로 업데이트됩니다
const { status, data, error } = useQuery({
queryKey: ["todo", { id: 5 }],
queryFn: fetchTodoById,
});
재사용 가능한 뮤테이션에 onSuccess
로직을 통합하고 싶다면, 다음과 같은 커스텀 훅을 만들 수 있습니다:
const useMutateTodo = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: editTodo,
// 두 번째 인자는 `mutate` 함수가 받는 변수 객체입니다
onSuccess: (data, variables) => {
queryClient.setQueryData(["todo", { id: variables.id }], data);
},
});
};
Immutablity
setQueryData
를 통해 업데이트할 때는 불변 방식으로 수행해야 합니다. 절대 캐시에서 가져온 데이터를 직접 수정하려고 하지 마세요. 처음에는 잘 작동할 수 있지만, 이후에 미묘한 버그를 유발할 수 있습니다.
queryClient.setQueryData(["posts", { id }], (oldData) => {
if (oldData) {
// ❌ 이렇게 시도하지 마세요
oldData.title = "my new post title";
}
return oldData;
});
queryClient.setQueryData(
["posts", { id }],
// ✅ 이 방법을 사용하세요
(oldData) =>
oldData
? {
...oldData,
title: "my new post title",
}
: oldData
);