What is the useOptimistic hook?
Assesses fundamental understanding of React conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
useOptimistic enables optimistic UI updates - showing changes immediately before server confirmation.
#### Basic Usage
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
'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
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
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.