Blog>
Snippets

Implementing Optimistic Updates with TanStack Store

Provide an example of applying optimistic updates in a todo application, highlighting how to temporarily update the UI in response to user actions while the backend processes the request.
const { mutate } = useMutation(addTodo, {
  // Optimistic update
  onMutate: async newTodo => {
    await queryClient.cancelQueries('todos')
    const previousTodos = queryClient.getQueryData('todos')
    queryClient.setQueryData('todos', old => [...old, newTodo])
    return { previousTodos }
  },
  // On error, rollback to the previous value
  onError: (err, newTodo, context) => {
    queryClient.setQueryData('todos', context.previousTodos)
  },
  // After mutation or if mutation fails, refetch the todos
  onSettled: () => {
    queryClient.invalidateQueries('todos')
  },
});
This code snippet shows how to implement optimistic updates in a todo application using TanStack Query. When a new todo is added (`mutate` is called), it first cancels any outgoing refetches for query 'todos' to prevent them from overwriting our optimistic update. Then, it saves the current todos list before the mutation as `previousTodos` for potential rollback, and optimistically updates the list by adding the new todo. If an error occurs, the todos list is rolled back to `previousTodos`. Finally, regardless of success or error, `todos` is refetched after mutation settles to ensure the list reflects the latest server state.