React 19 - useOptimistic

This New hook: useOptimistic gives an example of how useOptimistic is used

const [optimisticName, setOptimisticName] = useOptimistic(currentName);

const submitAction = async formData => {
    const newName = formData.get("name");
    setOptimisticName(newName);
    const updatedName = await updateName(newName);
    onUpdateName(updatedName);
};

and it states

The useOptimistic hook will immediately render the optimisticName while the updateName request is in progress. When the update finishes or errors, React will automatically switch back to the currentName value.

It was confusing to me. If optimisticName just switches back to the currentName after the current async operation finishes then there must be another state to save the updated value. However the template code only uses one state - optimisticName.

<form action={submitAction}>
    <p>Your name is: {optimisticName}</p>
    <p>
    <label>Change Name:</label>
    <input
        type="text"
        name="name"
        disabled={currentName !== optimisticName}
    />
    </p>
</form>

So how does the UI show the updated name after the async op is done ? It took me a few reads to realize what’s going on here. It’s happening in the code that is not shown in the example. There’s probably a parent component of ChangeName that manages the persistent state. The data flow is a typical flow in React app:

  1. The onUpdateName prop is used to update the parent’s state.
  2. When the parent re-renders, it passes a new currentName to ChangeName.
  3. The new currentName value now becomes the initial value of optimisticName and will be used to show the updated name.

So the hidden code that is not included in the official example probably looks something like this:

function UserInfo() {
    const [name, setName] = useState('Zuck');
    return <ChangeName currentName={name} onUpdateName={newName => setName(newName)}>;
}