React & Modern Frontend (445 Qs)•Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)
What is the useOptimistic hook?
useOptimistic enables optimistic UI updates - showing changes immediately before server confirmation.
Basic Usage
jsx
import { useOptimistic } from 'react';
function TodoList({ todos, addTodo }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(currentTodos, newTodo) => [...currentTodos, { ...newTodo, pending: true }]
);
async function handleSubmit(formData) {
const title = formData.get('title');
// Immediately show optimistic update
addOptimisticTodo({ id: Date.now(), title });
// Send to server
await addTodo(title);
// Component re-renders with real data when complete
}
return (
<>
<form action={handleSubmit}>
<input name="title" />
<button>Add</button>
</form>
<ul>
{optimisticTodos.map(todo => (
<li key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
{todo.title}
{todo.pending && ' ⏳'}
</li>
))}
</ul>
</>
);
}
With Server Actions
jsx
'use client'
import { useOptimistic } from 'react';
import { likePost } from './actions';
export default function Post({ post, likes }) {
const [optimisticLikes, addOptimisticLike] = useOptimistic(
likes,
(currentLikes, amount) => currentLikes + amount
);
async function handleLike() {
addOptimisticLike(1); // Immediate UI update
await likePost(post.id); // Server update
}
return (
<div>
<h2>{post.title}</h2>
<button onClick={handleLike}>
❤️ {optimisticLikes} Likes
</button>
</div>
);
}
Complex Example with Error Handling
jsx
function ShoppingCart({ items, removeItem }) {
const [optimisticItems, removeOptimistic] = useOptimistic(
items,
(current, removedId) => current.filter(item => item.id !== removedId)
);
async function handleRemove(itemId) {
removeOptimistic(itemId); // Immediate removal from UI
try {
await removeItem(itemId);
} catch (error) {
// Automatic rollback on error!
toast.error('Failed to remove item');
}
}
return (
<ul>
{optimisticItems.map(item => (
<li key={item.id}>
{item.name}
<button onClick={() => handleRemove(item.id)}>Remove</button>
</li>
))}
</ul>
);
}
When to Use
- ✅ Toggling likes/favorites
- ✅ Adding/removing items from lists
- ✅ Sending messages in chat
- ✅ Any action where immediate feedback improves UX
- ❌ Financial transactions (wait for confirmation)
- ❌ Critical operations requiring server validation