[TIL] React Query - Optimistic Updates

React Query

Optimistic Updates

mutation을 수행하기 전에 상태를 optimistically 업데이트하면 mutation이 실패할 가능성이 있다. 이러한 실패 사례 대부분은 optimistic 쿼리에 대해 리페치를 트리거하여 실제 서버 상태로 되돌릴 수 있다. 리페칭이 불가능한 서버 문제가 있을 경우에는 제대로 작동하지 않을 수 있다. 이 경우에는 업데이트를 롤백하도록 선택할 수 있다.

이를 하려면 useMutationonMutate 핸들러 옵션을 사용하면 나중에 onError onSettled 핸들러에 모두 전달될 값을 마지막 인수로 반환할 수 있다. 주로 롤백함수를 전달하는 것이 유용하다.

새로운 todo가 추가될 때 todo 리스트 업데이트

const queryClient = useQueryClient();

useMutation({
  mutationFn: updateTodo,
  onMutate: async (newTodo) => {
    // 다른 refetch 취소
    // (optimistic update를 덮어씌우지 않도록 하기 위함)
    await queryClient.cancelQueries({ queryKey: ["todos"] });

    // 이전 값들 스냅샷
    const previousTodos = queryClient.getQueryData(["todos"]);

    // 새로운 값 Optimistically update
    queryClient.setQueryData(["todos"], (old) => [...old, newTodo]);

    // 스냅샷한 값들로 context 객체 리턴
    return { previousTodos };
  },
  // mutation 실패시
  // context 사용하여 이전 결과로 롤백
  onError: (err, newTodo, context) => {
    queryClient.setQueryData(["todos"], context.previousTodos);
  },
  // error나 success시 항상 refetch
  onSettled: () => {
    queryClient.invalidateQueries({ queryKey: ["todos"] });
  },
});

참고