useOptimistic is a React Hook that lets you show a different state while an async action is underway.
Parameters
S
required
The value to be returned initially and whenever no action is pending.
(state: S, action: A) => S
Optional function that takes the current state and an action, and returns the optimistic state to use while the action is pending.If omitted, the action itself is used as the new state.
Returns
useOptimistic returns an array with exactly two values:
S
The optimistic state. It equals
passthrough when no action is pending, otherwise it equals the value returned by reducer.(action: A) => void
The
addOptimistic function that you call to add an optimistic update. It takes one argument of any type (the optimistic action), and will call the reducer with passthrough and the action.Usage
Optimistically updating forms
useOptimistic provides a way to optimistically update the user interface before a background operation, like a network request, completes:
Building an optimistic update mechanism
The optimistic state is automatically reset when the action completes:Common Patterns
Todo list with optimistic adds
- Basic
- With Delete
Like button with optimistic update
Comments with optimistic adds
Shopping cart with optimistic updates
TypeScript
Without reducer
Troubleshooting
My optimistic update doesn’t revert
The optimistic state automatically reverts when:- The component re-renders with new
passthroughvalue - The async operation completes and the parent updates the real state
The optimistic state looks wrong
Make sure your reducer returns the correct optimistic state:Multiple optimistic updates conflict
If you need multiple independent optimistic updates, use separateuseOptimistic hooks:
Best Practices
Show pending state visually
Handle errors gracefully
Use with Server Actions
Combine with useActionState
When to use useOptimistic
UseuseOptimistic when:
- ✅ You want immediate UI feedback
- ✅ The operation is likely to succeed
- ✅ You can easily revert on failure
- ✅ Network latency would make the UI feel slow
- ❌ The operation might fail frequently
- ❌ Reverting would confuse users
- ❌ The operation has side effects that can’t be undone
- ❌ The UI is already fast enough