Blog>
Snippets

Optimistic Updates Example

Provide an example of how to implement optimistic updates in a React application using React Query, allowing the UI to update immediately while the mutation request is being processed.
import { useMutation, useQueryClient } from 'react-query';
import axios from 'axios';
Import necessary hooks and axios for making HTTP requests.
// Define the optimistic update function
const updateTodoOptimistically = (todoId, newTodo) => {
  const queryClient = useQueryClient();

  // Cancel any outgoing refetches (so they don't overwrite our optimistic update)
  queryClient.cancelQueries('todos');

  // Snapshot previous value
  const previousTodos = queryClient.getQueryData('todos');

  // Optimistically update to the new value
  queryClient.setQueryData('todos', old =>
    old.map(todo =>
      todo.id === todoId ? { ...todo, ...newTodo } : todo
    )
  );

  return () => queryClient.setQueryData('todos', previousTodos);
};
Defines the optimistic update function. It snapshots the previous state, updates the data optimistically, and returns a rollback function to reset the data if needed.
const mutation = useMutation(
  ({todoId, newTodo}) => axios.put(`https://jsonplaceholder.typicode.com/todos/${todoId}`, newTodo),
  {
    // When mutate is called:
    onMutate: async ({todoId, newTodo}) => {
      // Call the optimistic update function
      return updateTodoOptimistically(todoId, newTodo);
    },
    onError: (err, newTodo, rollback) => rollback(),
    // Always refetch after error or success:
    onSettled: () => {
      const queryClient = useQueryClient();
      queryClient.invalidateQueries('todos');
    },
  }
);
Use the useMutation hook to define how to mutate (update) the data, how to optimistically update the UI before the mutation is completed, and how to rollback in case of an error.