Optimistic Updates
A UI pattern where the interface immediately reflects a user's action as if it succeeded, then reconciles with the server response asynchronously—rolling back on failure.
Description
Optimistic updates are a UX-driven state management technique where the client immediately applies a mutation to the local UI state before the server confirms the change. This makes the application feel instantaneous, eliminating the perceived latency of network round-trips. When the server responds successfully, the optimistic update is confirmed (and optionally reconciled if the server's response differs). When the server responds with an error, the update is rolled back to the previous state and the user is notified of the failure.
Implementing optimistic updates requires careful state management. You need to: capture a snapshot of the current state before applying the optimistic change, apply the change to the local cache or store immediately, send the mutation to the server, confirm the update on success (or replace the optimistic data with the server's canonical response), and roll back to the snapshot on failure. Libraries like React Query (useMutation with onMutate/onError/onSettled), Apollo Client (optimisticResponse), and SWR (mutate with optimisticData) provide built-in support for this pattern.
The subtlety lies in handling concurrent mutations and maintaining consistency. If a user rapidly likes and unlikes a post, the optimistic state must track the latest intent while multiple network requests are in flight. Edge cases include: handling mutations that fail after subsequent mutations have already been applied optimistically, reconciling list ordering when an optimistic insert conflicts with server-side sorting, and deciding whether to show error toasts or silently retry. Optimistic updates are most appropriate for low-risk, easily reversible actions (likes, toggles, reordering) and less suitable for destructive or financially significant operations.
Prompt Snippet
Implement optimistic updates for the task list using React Query's useMutation with onMutate for immediate cache updates via queryClient.setQueryData, capturing the previous task list as a snapshot in the onMutate return value. In onError, roll back using the snapshot from the onMutate context and display a non-blocking toast notification. In onSettled, call queryClient.invalidateQueries to refetch and reconcile with the server's canonical state. For concurrent mutations, use queryClient.cancelQueries before each onMutate to prevent in-flight queries from overwriting optimistic state. Add a 5-second undo toast using a deferred setTimeout that cancels the actual server mutation if the user clicks undo.
Tags
Related Terms
Cache Invalidation Strategies
Techniques for determining when cached data is stale and must be refreshed, including time-based expiry, event-based invalidation, and tag-based dependency tracking.
Stale-While-Revalidate
A caching strategy that immediately returns cached (potentially stale) data to the caller while asynchronously revalidating the cache in the background.
Component-Level vs Global State
The architectural decision of whether state should live within a single component, be lifted to a shared ancestor, or be placed in a global store based on its scope and consumer count.
WebSocket State Synchronization
A pattern for keeping client-side state synchronized with server-side state in real time using persistent WebSocket connections that push updates as they occur.