React 19 useOptimistic: Patterns and Pitfalls in Real Forms
React 19's useOptimistic shows results before server confirmation. Battle-tested patterns from a comment box, like button and settings form, plus three costly pitfalls.
React 19's useOptimistic hook lets an interface show an action's result before the server confirms it. The API surface is minimal, but the mental model trips people up: the hook holds no durable state — it's simply a transient view over real state that exists only while a transition is pending. Once the action resolves and real state updates, React discards the optimistic value and re-renders from truth, with no manual rollback needed.
Three patterns hold up in practice: appending a new comment optimistically (with a pending flag for dimmed styling), toggling a like count (since the reducer receives the current optimistic value, rapid clicks compose correctly instead of racing a stale closure), and instant feedback in settings forms. Three pitfalls, however, each cost an afternoon: calling addOptimistic from a plain onClick causes the value to flash and vanish because no transition keeps it alive — it must be triggered inside a form action or startTransition. Second, useOptimistic has no built-in error channel; when the action throws, the optimistic value silently disappears, so it needs to be paired with useActionState or a toast for user feedback. Third, reusing a fixed placeholder ID for pending rows causes React to merge concurrent entries — each optimistic item needs a unique temporary key.
The author notes deliberately avoiding useOptimistic for low-confidence writes like payments or destructive deletes, arguing that showing unguaranteed success erodes user trust faster than an honest loading spinner. These lessons offer a practical checklist for teams adopting React 19.