facebook/react · error · Error

Cannot update optimistic state while rendering.

Error message

Cannot update optimistic state while rendering.

What it means

The SSR renderer (Fizz) implements useOptimistic as a stub: during server rendering it returns the passthrough value unchanged plus a dispatch function (unsupportedSetOptimisticState) that always throws. The server keeps no update queue, so any attempt to apply an optimistic update while rendering on the server fails immediately with this error.

Source

Thrown at packages/react-server/src/ReactFizzHooks.js:659

function unsupportedStartTransition() {
  throw new Error('startTransition cannot be called during server rendering.');
}

function useTransition(): [
  boolean,
  (callback: () => void, options?: StartTransitionOptions) => void,
] {
  resolveCurrentlyRenderingComponent();
  return [false, unsupportedStartTransition];
}

function useHostTransitionStatus(): TransitionStatus {
  resolveCurrentlyRenderingComponent();
  return NotPendingTransition;
}

function unsupportedSetOptimisticState() {
  throw new Error('Cannot update optimistic state while rendering.');
}

function useOptimistic<S, A>(
  passthrough: S,
  reducer: ?(S, A) => S,
): [S, (A) => void] {
  resolveCurrentlyRenderingComponent();
  return [passthrough, unsupportedSetOptimisticState];
}

function createPostbackActionStateKey(
  permalink: string | void,
  componentKeyPath: KeyNode | null,
  hookIndex: number,
): string {
  if (permalink !== undefined) {
    // Don't bother to hash a permalink-based key since it's already short.
    return 'p' + permalink;

View on GitHub (pinned to eafeac097b)

Solutions

  1. Call the optimistic setter only from client-side event handlers, form actions, or transition callbacks
  2. If you need a derived initial value during render, compute it and pass it as the passthrough argument instead of dispatching
  3. Move the interactive logic into a component marked 'use client' so it never executes during SSR

Example fix

// before
function Todo({todo}) {
  const [optimistic, addOptimistic] = useOptimistic(todo, reducer);
  addOptimistic({done: true}); // dispatch during render -> throws during SSR
  return <li>{optimistic.text}</li>;
}

// after
function Todo({todo}) {
  const [optimistic, addOptimistic] = useOptimistic(todo, reducer);
  // dispatch only from an event handler (runs on the client after hydration)
  return <button onClick={() => addOptimistic({done: true})}>{optimistic.text}</button>;
}
Defensive patterns

Strategy: type-guard

Prevention

When it happens

Trigger: Invoking the second element returned by useOptimistic() while a component renders on the server: dispatching during render (derived-state pattern), calling the setter from a helper that the SSR pass executes, or calling it inside logic shared between client and server that runs during SSR.

Common situations: Components shared between client and SSR that call the optimistic setter during render; React 19 useOptimistic adoption in code paths that also execute on the server; dispatching at module scope or in top-level code the server evaluates.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/f5aaf48ba015915e. Report an issue: GitHub.