useOptimistic value reverts before the server action actually resolves
useOptimistic's optimistic value only stays applied while its underlying transition is still pending — if the update function that changes the real state isn't wrapped in the same transition (e.g. a `startTransition` or a form Action), React reverts to actual state as soon as the surrounding render settles, not when the async work finishes.
What causes this error
useOptimistic shows a temporary value only for the duration of the transition that triggered it. If the actual state-updating call isn't part of that same transition — for example, it's fired in a plain `async` click handler instead of a Server Action or `startTransition` — React has no pending transition to tie the optimistic value to, and it snaps back to real state almost immediately.
The Fix
// Wrong — optimistic update and real update aren't in the same transition
function Likes({ likes, addLike }) {
const [optimisticLikes, setOptimisticLikes] = useOptimistic(likes);
async function handleClick() {
setOptimisticLikes((n) => n + 1);
await addLike(); // not wrapped — optimistic value reverts before this resolves
}
}
// Fix — use a Server Action / form Action, which React ties to the transition automatically
function Likes({ likes, addLikeAction }) {
const [optimisticLikes, setOptimisticLikes] = useOptimistic(likes);
async function action() {
setOptimisticLikes((n) => n + 1);
await addLikeAction();
}
return (
<form action={action}>
<button>{optimisticLikes} likes</button>
</form>
);
}Common causes / variations
- Calling the real update outside `startTransition`/a form Action instead of inside it
- The server update failing silently, so React reverts to the (unchanged) real state with no visible error
- Using `useOptimistic` on state that isn't actually derived from the value being updated
Related errors
See also: useFormStatus must be used within a form, Too many re-renders.
Comments
Loading comments...