Optimistic UI in React with useOptimistic

A
Author
01 Sep, 2026 1 min read 692 views

When a user likes a post or sends a message, waiting for the server before updating the screen feels sluggish. Optimistic UI shows the result immediately and corrects it if the request fails.

The hook

const [optimisticState, addOptimistic] = useOptimistic(actualState, (current, optimisticValue) => newState);

While an action is running, optimisticState includes your optimistic changes. When the action finishes, it falls back to actualState, which by then should hold the real server data.

A chat example

import { useOptimistic, useState } from 'react';

export default function Chat({ initialMessages }) {
  const [messages, setMessages] = useState(initialMessages);
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (current, text) => [...current, { id: crypto.randomUUID(), text, sending: true }]
  );

  async function send(formData) {
    const text = formData.get('text');
    addOptimisticMessage(text);              // shows instantly
    const saved = await api.sendMessage(text); // real request
    setMessages((m) => [...m, saved]);       // replace with server data
  }

  return (
    <>
      <ul>
        {optimisticMessages.map((m) => (
          <li key={m.id} style={{ opacity: m.sending ? 0.6 : 1 }}>
            {m.text} {m.sending && <small>(sending...)</small>}
          </li>
        ))}
      </ul>
      <form action={send}>
        <input name="text" />
        <button>Send</button>
      </form>
    </>
  );
}

What happens on failure?

If api.sendMessage throws, setMessages never runs. When the action ends, the optimistic message disappears because the real state never included it. Catch the error to show a message such as "Couldn't send, tap to retry".

Good candidates

  • Likes, stars, bookmarks and toggles.
  • Adding items to a list (todos, comments, chat).
  • Reordering with drag and drop.

Avoid optimistic updates for things users must not misunderstand, such as payments or irreversible deletes.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.