Blog/Quick Tips & Snippets/React useOptimistic: Instant UI Updates Done Right
POST
April 22, 2025
LAST UPDATEDApril 22, 2025

React useOptimistic: Instant UI Updates Done Right

Learn how to use React's useOptimistic hook with Server Actions to show instant UI feedback while mutations complete in the background.

Tags

ReactHooksServer ActionsUI
React useOptimistic: Instant UI Updates Done Right
2 min read

React useOptimistic: Instant UI Updates Done Right

TL;DR

The useOptimistic hook shows instant UI changes while a Server Action runs in the background, automatically reverting if the action fails.

The Problem

When a user submits a form or toggles a like button, the UI traditionally waits for the server to respond before updating. This delay makes the app feel sluggish, especially on slow connections. You could manually manage pending states, but that means tracking optimistic values, error rollbacks, and race conditions yourself.

The Solution

Use useOptimistic to immediately show the expected result:

tsx
"use client";
 
import { useOptimistic } from "react";
import { toggleLike } from "@/app/actions";
 
type Message = {
  id: string;
  text: string;
  likes: number;
  likedByUser: boolean;
};
 
export function MessageCard({ message }: { message: Message }) {
  const [optimisticMessage, setOptimisticMessage] = useOptimistic(
    message,
    (current, newLikedState: boolean) => ({
      ...current,
      likedByUser: newLikedState,
      likes: newLikedState ? current.likes + 1 : current.likes - 1,
    })
  );
 
  async function handleToggleLike() {
    const newState = !optimisticMessage.likedByUser;
    setOptimisticMessage(newState); // instant UI update
    await toggleLike(message.id);  // server action runs in background
  }
 
  return (
    <div>
      <p>{optimisticMessage.text}</p>
      <button onClick={handleToggleLike}>
        {optimisticMessage.likedByUser ? "Unlike" : "Like"} ({optimisticMessage.likes})
      </button>
    </div>
  );
}

The like count updates immediately on click. If the Server Action fails, React automatically reverts to the real server state on the next render.

Why This Works

useOptimistic takes two arguments: the actual state from the server and a reducer function that computes the optimistic version. When you call the setter, React immediately renders with the optimistic value. Under the hood, React tracks that a transition is pending. Once the Server Action completes (or the parent re-renders with fresh server data), React replaces the optimistic state with the real state. If the action throws, the optimistic value is discarded and the UI snaps back to reality -- no manual rollback logic required.

Collaboration

Need help with a project?

Let's Build It

I help startups and established companies design, build, and scale world-class digital products. From deep technical architecture to pixel-perfect UI — let's bring your vision to life.

SH

Article Author

Sadam Hussain

Senior Full Stack Developer

Senior Full Stack Developer with over 7 years of experience building React, Next.js, Node.js, TypeScript, and AI-powered web platforms.

Related Articles

TypeScript Utility Types You Should Know
Feb 10, 20263 min read
TypeScript
Cheatsheet

TypeScript Utility Types You Should Know

Five essential built-in generic utility types in TypeScript that will save you hundreds of lines of code.

Generate Dynamic OG Images in Next.js
Feb 08, 20262 min read
Next.js
OG Images
SEO

Generate Dynamic OG Images in Next.js

Generate dynamic Open Graph images in Next.js using the ImageResponse API with custom fonts, gradients, and data-driven content for social sharing.

GitHub Actions Reusable Workflows: Stop Repeating Yourself
Jan 22, 20263 min read
GitHub Actions
CI/CD
DevOps

GitHub Actions Reusable Workflows: Stop Repeating Yourself

Create reusable GitHub Actions workflows with inputs, secrets, and outputs to eliminate YAML duplication across repositories and teams efficiently.