Přeskočit na obsah

useOptimistic: UI, které nečeká na server

Lajk, který se rozsvítí okamžitě, a zpráva, která se v chatu objeví dřív, než ji server uloží. A když něco selže, React stav sám vrátí.

Autor
Jan Jarčík
Publikováno
Doba čtení
2 min čtení
Aktualizováno
SdíletXLinkedInBluesky

Optimistické UI je trik, díky kterému aplikace působí bleskově: výsledek akce ukážete hned a server ho potvrdí na pozadí. V React 19 na to máme hook useOptimistic.

Signatura

TypeScript
const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
  • state — „pravdivá“ hodnota (např. z props nebo ze serveru),
  • updateFn(current, optimisticValue) — čistá funkce, která vrátí optimistickou verzi,
  • addOptimistic(value) — zavoláte uvnitř akce nebo startTransition.

Dokud akce běží, renderuje se optimisticState. Jakmile skončí, React se vrátí k aktuálnímu state — ať už akce uspěla (a state obsahuje novou položku), nebo selhala (a optimistická změna prostě zmizí).

Příklad: chat

TSX
"use client";
import { useOptimistic } from "react";
 
type Message = { id: string; text: string; sending?: boolean };
 
export function Thread({ messages, send }: {
  messages: Message[];
  send: (text: string) => Promise<void>;
}) {
  const [optimistic, addMessage] = useOptimistic(
    messages,
    (current, text: string) => [
      ...current,
      { id: crypto.randomUUID(), text, sending: true },
    ],
  );
 
  async function action(formData: FormData) {
    const text = String(formData.get("text"));
    addMessage(text);
    await send(text); // server action, poté revalidace dat
  }
 
  return (
    <>
      <ul>
        {optimistic.map((m) => (
          <li key={m.id} style={{ opacity: m.sending ? 0.5 : 1 }}>{m.text}</li>
        ))}
      </ul>
      <form action={action}>
        <input name="text" />
      </form>
    </>
  );
}

Na co si dát pozor

  • addOptimistic mimo akci nebo transition vyvolá varování a změna se okamžitě zahodí.
  • Optimistický stav je dočasný. Zdroj pravdy musí po akci přijít z state — typicky revalidací dat nebo setState uvnitř transition.
  • Ukažte uživateli, že položka se teprve ukládá (průhlednost, ikonka hodin). Optimismus neznamená lhaní.