Optimistic Updates | TanStack Query Docs

새 할일을 추가할 때 할일 목록 업데이트

const queryClient = useQueryClient()

useMutation({
  mutationFn: updateTodo,
  // mutate가 호출되는 경우
  onMutate: async (newTodo) => {
    // 다시 가져오기 취소
    // 서버로 오는 데이터가 긍정적인 업데이트를 덮어쓰는 일이 없도록 해줌 
    await queryClient.cancelQueries({ queryKey: ['todos'] })

    // Snapshot the previous value 이전값의 스냅샷
    const previousTodos = queryClient.getQueryData(['todos'])

    // 낙관적인 새 값으로 업데이트 합니다.
    queryClient.setQueryData(['todos'], (old) => [...old, newTodo])

    // 스냅샷된 값으로 컨텍스트 객체를 반환합니다.
    return { previousTodos }
  },
  // mutation이 실패하는 경우 
  // onMutate에서 반환된 컨텍스트를 사용해 롤백합니다.
  onError: (err, newTodo, context) => {
    queryClient.setQueryData(['todos'], context.previousTodos)
  },
  // 오류나 성공 후에는 항상 다시 가져옵니다.
  onSettled: () => {
    queryClient.invalidateQueries({ queryKey: ['todos'] })
  },
})

참고2

단일 할일 업데이트

useMutation({
  mutationFn: updateTodo,
  // mutate가 호출되는 경우
  onMutate: async (newTodo) => {
    // Cancel any outgoing refetches
    // (so they don't overwrite our optimistic update)
    await queryClient.cancelQueries**({ queryKey: ['todos', newTodo.id] })**

    // Snapshot the previous value
    const previousTodo = queryClient.getQueryData**(['todos', newTodo.id])**

    // Optimistically update to the new value
    queryClient.setQueryData**(['todos', newTodo.id], newTodo)**

    // Return a context with the previous and new todo
    return **{ previousTodo, newTodo }**
  },
  // If the mutation fails, use the context we returned above
  onError: (err, newTodo, context) => {
    queryClient.setQueryData(
      ['todos', context.newTodo.id],
      context.previousTodo,
    )
  },
  // Always refetch after error or success:
  onSettled: (newTodo) => {
    queryClient.invalidateQueries({ queryKey: ['todos', newTodo.id] })
  },
})

원하는 경우 별도의 onErroronSuccess 핸들러 대신 onSettled 함수를 사용할 수도 있습니다.

useMutation({
  mutationFn: updateTodo,
  // ...
  onSettled: (newTodo, error, variables, context) => {
    if (error) {
      // do something
    }
  },
})