React 19's useOptimistic
hook lets you update your UI to its expected state after an asynchronous action while the action is still in progress.
Imagine you have an app that lets you add comments to some published content. When you add a new comment, a network request is made to the server to create the comment in the app's database.
This process takes time, so you need to account for this in your UI state. The flow might look something like this:
Make a
POST
request to create a new commentShow a loading spinner in your UI
After the
POST
request finishes, make aGET
request to fetch the latest list of comments, which should include your new commentRemove the loading spinner and show the updated comments
The useOptimisitic hook makes your UI feel snappier
Instead of showing a loading spinner and waiting for all your requests to resolve, you can use the useOptimistic
hook to immediately add the comment. If the request fails, you can remove the comment and show an error message. The happy path feels much faster and it's easy to recover from the failure path.
The example below shows how this might work by combining the new useActionState
hook with the useOptimistic
hook.
If you're unfamiliar with how the
useActionState
hook works, you can learn more in my post about React 19 actions and form actions.
You'll notice we show a loading message when you submit a comment. But that's not the only thing we do. We also immediately show the comment in the comment section because we update the optimistic value. This optimistic value has an extra unsaved
property that we use to style the comment differently.
Once the request finishes, we update the actual comments
state which includes the newly created comment. This time, however, the comment isn't in an unsaved state, so it's styled normally.
To handle errors, we show a toast message and return the old list of comments. When the component re-renders, the useOptimistic
hook will detect this, which will remove the optimistically added comment.
To try this out, you can pass the text error
to the comment form.
And that's it! Hopefully, this post helps you build snappier UIs with React 19's new useOptimistic
hook!