Rollback optimistic update on mutation error
Show how to revert optimistic updates when a mutation fails by using the onError callback within the useMutation hook.
const { mutate } = useMutation(updateTodo, {
onMutate: async (todo) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries('todos');
// Snapshot the previous value
const previousTodos = queryClient.getQueryData('todos');
// Optimistically update to the new value
queryClient.setQueryData('todos', old => old.map(t => t.id === todo.id ? { ...t, ...todo } : t));
// Return a context with the previous and new todo for potential rollback
return { previousTodos };
},
onError: (err, todo, context) => {
// Rollback to the previous value
queryClient.setQueryData('todos', context.previousTodos);
},
onSettled: () => {
// Refetch after success or failure
queryClient.invalidateQueries('todos');
},
});
This code snippet shows how to implement an optimistic update with a rollback on error using React Query's useMutation hook. When the `updateTodo` mutation is initiated, `onMutate` snaps a picture of the current todos and optimistically updates the UI. If the mutation encounters an error, `onError` rolls back the UI to its previous state using the snapshot taken earlier. Finally, `onSettled` ensures that the data is refetched from the server regardless of the mutation's outcome.