Optimistic updates improve perceived performance by updating the UI before the server confirms the change. Libraries like React Query (TanStack Query) simplify this. Use the onMutate option in useMutation to:

  • Cancel relevant ongoing queries.
  • Snapshot the current state.
  • Update the local cache optimistically.
  • Return the snapshot.
  • Use onError to roll back the cache using the snapshot if the mutation fails. Use onSettled to refetch/invalidate queries ensuring eventual consistency.

Using React Query’s useMutation:

const mutation = useMutation(updateItem, { onMutate: async (newItem) => { await queryClient.cancelQueries('items'); const previousData = queryClient.getQueryData('items'); queryClient.setQueryData('items', (old) => [...old, newItem]); return { previousData }; }, onError: (err, newItem, context) => { queryClient.setQueryData('items', context.previousData); }, onSettled: () => { queryClient.invalidateQueries('items'); },
});