When users post a comment, like a post, or update a setting, traditional web applications show a loading spinner while waiting for the server response. This latency creates a sluggish experience.
Optimistic UI is a pattern where the application immediately updates the screen assuming the server operation will succeed. With **React 19**, Meta introduced the native useOptimistic hook to manage optimistic state seamlessly and roll back automatically if the background operation fails.
1. How `useOptimistic` Works
The useOptimistic hook takes two arguments: the current actual state, and an update function that merges optimistic changes. It returns a tuple containing the optimistic state and an optimistic dispatch function.
currentState,
(state, optimisticValue) => {
// Return updated state combining current state and optimistic value
return [...state, { ...optimisticValue, sending: true }];
}
);
2. Real-World Code Example: Real-Time Chat Message List
Here is a practical example of a chat application using useOptimistic to display new messages instantly while sending them to the backend server:
export default function ChatApp({ messages, sendMessageAction }) {
const formRef = useRef(null);
// 1. Define optimistic state for messages
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessageText) => [
...state,
{ text: newMessageText, id: Date.now(), sending: true }
]
);
async function formAction(formData) {
const text = formData.get('message');
formRef.current.reset();
// 2. Trigger instant UI update
addOptimisticMessage(text);
// 3. Perform background server action
await sendMessageAction(text);
}
return (
<div className="p-3 bg-light rounded">
<ul className="list-group mb-3">
{optimisticMessages.map((msg) => (
<li key={msg.id} className="list-group-item d-flex justify-content-between align-items-center">
{msg.text}
{msg.sending && <span className="badge bg-warning text-dark">Sending...</span>}
</li>
))}
</ul>
<form ref={formRef} action={formAction} className="d-flex gap-2">
<input name="message" className="form-control" placeholder="Type a message..." required />
<button type="submit" className="btn btn-danger">Send</button>
</form>
</div>
);
}
3. Automatic Error Rollback & State Recovery
If the background server action fails or throws an exception, React automatically reverts optimisticMessages back to the true server state (messages). Developers don't need to write manual try/catch cleanup logic for state reversion!
4. Comparison Table
| Pattern | User Feedback Latency | Implementation Complexity |
|---|---|---|
| Traditional Spinner | High (waits 500ms - 2s for network) | Low (standard isLoading boolean) |
| Manual Optimistic UI | Zero (Instant) | High (requires manual state rollbacks & error handling) |
React 19 useOptimistic |
Zero (Instant) | Low (Built-in state merging & auto rollback) |
Learn Full-Stack React 19 Development
Master React 19 hooks, Server Actions, and Next.js App Router in Telugu IT Tutorials' online coding classes. Explore Courses →