Lesson 73 of 80
React's built-in primitive for showing the assumed-successful result of an action immediately, then reconciling with reality once the real response lands.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Optimistic UI means showing the user the result you expect an action to have, before the server has actually confirmed it — a like button that fills in the instant you click it, not 200ms later when the network request resolves. useOptimistic is React's built-in hook for this exact pattern. It gives you a temporary, local value that automatically falls back to your real state once that real state updates (or the component re-renders for any other reason).
This automates something people have always hand-built: a second piece of state holding "the value I'm assuming is true," shown instead of the real value while a request is in flight, then discarded once the real value catches up. useOptimistic doesn't add new capability so much as it removes the bookkeeping — you stop writing the temporary-state-plus-manual-reset code yourself.
import { useOptimistic, useState } from "react";
function LikeButton({ postId, initialLikes }) {
const [likes, setLikes] = useState(initialLikes);
const [optimisticLikes, addOptimisticLike] = useOptimistic(
likes,
(currentLikes, amount) => currentLikes + amount
);
async function handleLike() {
addOptimisticLike(1); // shows +1 immediately, no network wait
const updated = await likePost(postId); // the real request
setLikes(updated.likes); // real state updates, optimistic value resets
}
return <button onClick={handleLike}>{optimisticLikes} likes</button>;
}
useOptimistic(likes, updateFn) takes the real, confirmed state (likes) and an update function describing how to compute a temporary value from it. Calling addOptimisticLike(1) doesn't touch likes at all — it produces optimisticLikes, a value the hook shows instead of likes for the current render. Once setLikes(updated.likes) actually changes the real state, React re-renders, and optimisticLikes collapses back to being the same as likes — the temporary value only exists between the optimistic update and the next time the base state changes.
likePost throws and you never call setLikes, the optimistic +1 can linger on screen looking confirmed when it isn't. Wrap the request in a try/catch and update the real state (even to its current value, to force a reset) on failure.useState for the assumed value, shown conditionally while a request is pending, cleared in a finally or catch. useOptimistic is that exact bookkeeping, built into React, so you stop re-implementing it in every component that needs it.(currentLikes, amount) => currentLikes + amount, for the same reason a reducer must be pure. It can be called more than once for a single optimistic update if React needs to.Before this hook existed, "optimistic UI" meant a second piece of local state holding the assumed value, shown instead of the real one while a request was in flight, and manually cleared once the real value came back or the request failed. useOptimistic is React formalizing that exact bookkeeping as a primitive — the underlying idea (show the guess, then reconcile with reality) hasn't changed, only how much of it you have to write yourself.