facebook/react · error · Error

485

485

Error message

Cannot update action state while rendering.

What it means

dispatchActionState backs the dispatch/formAction returned by useActionState. It unconditionally refuses to enqueue while isRenderPhaseUpdate(fiber) is true — that is, while React is currently rendering the component that owns the hook. Unlike setState (which permits a self-update during render to derive state), action-state updates always throw when dispatched during render.

Source

Thrown at packages/react-reconciler/src/ReactFiberHooks.js:2114

  // Implements the Thenable interface. We use it to suspend until the action
  // finishes.
  then: (listener: () => void) => void,
  status: 'pending' | 'rejected' | 'fulfilled',
  value: any,
  reason: any,
  listeners: Array<() => void>,
};

function dispatchActionState<S, P>(
  fiber: Fiber,
  actionQueue: ActionStateQueue<S, P>,
  setPendingState: boolean => void,
  setState: Dispatch<ActionStateQueueNode<S, P>>,
  payload: P,
): void {
  if (isRenderPhaseUpdate(fiber)) {
    throw new Error('Cannot update action state while rendering.');
  }

  const currentAction = actionQueue.action;
  if (currentAction === null) {
    // An earlier action errored. Subsequent actions should not run.
    return;
  }

  const actionNode: ActionStateQueueNode<S, P> = {
    payload,
    action: currentAction,
    next: null as any, // circular
    isTransition: true,

    status: 'pending',
    value: null,
    reason: null,
    listeners: [],

View on GitHub (pinned to eafeac097b)

Solutions

  1. Move the call into an event handler, a <form action={...}> submission, or the action function itself
  2. For run-once-on-mount behavior, call the action from useEffect
  3. If you were trying to derive state during render, compute it from props/state instead of dispatching
  4. Add a lint step (react-hooks rules) and review any function called unconditionally in the component body

Example fix

// before
function Cart() {
  const [items, addItem] = useActionState(addItemAction, []);
  addItem(defaultItem); // throws: dispatched while rendering
}

// after
function Cart({defaultItem}) {
  const [items, addItem] = useActionState(addItemAction, []);
  useEffect(() => {
    if (defaultItem) addItem(defaultItem); // dispatch after render
  }, []);
}
Defensive patterns

Strategy: try-catch

Try / catch

// Render-phase throw: an error boundary keeps the app alive while you fix the call site
<ErrorBoundary fallback={<FormFallback/>} onError={(e) => warnDeveloper('do not dispatch useActionState during render', e)}>
  <CheckoutForm />
</ErrorBoundary>

Prevention

When it happens

Trigger: Calling the formAction (or dispatch) returned by useActionState from the component body, from a hook callback executing during render (e.g. inside a useMemo/useReducer argument evaluated synchronously), or from a child's render — i.e. any dispatch while that fiber is still being rendered.

Common situations: Accidentally invoking the action in the component body (missing onSubmit wiring); auto-submitting on mount by calling the action during render; passing the action to code that immediately calls it during render; refactoring event handlers into render helpers.

Related errors


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