facebook/react · error · Error

takes an object of state variables to update or a function w

Error message

takes an object of state variables to update or a function which returns an object of state variables.

What it means

React.Component.prototype.setState validates its first argument: it must be an object of partial state, an updater function, or null/undefined (which bail out). Passing any other primitive (string, number, boolean, symbol, bigint) throws this error before anything is enqueued.

Source

Thrown at packages/react/src/ReactBaseClasses.js:62

 * the future (not synchronously). It will be called with the up to date
 * component arguments (state, props, context). These values can be different
 * from this.* because your function may be called after receiveProps but before
 * shouldComponentUpdate, and this new state, props, and context will not yet be
 * assigned to this.
 *
 * @param {object|function} partialState Next partial state or function to
 *        produce next partial state to be merged with current state.
 * @param {?function} callback Called after state is updated.
 * @final
 * @protected
 */
Component.prototype.setState = function (partialState, callback) {
  if (
    typeof partialState !== 'object' &&
    typeof partialState !== 'function' &&
    partialState != null
  ) {
    throw new Error(
      'takes an object of state variables to update or a ' +
        'function which returns an object of state variables.',
    );
  }

  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

/**
 * Forces an update. This should only be invoked when it is known with
 * certainty that we are **not** in a DOM transaction.
 *
 * You may want to call this when you know that some deeper aspect of the
 * component's state has changed but `setState` was not called.
 *
 * This will not invoke `shouldComponentUpdate`, but it will invoke
 * `componentWillUpdate` and `componentDidUpdate`.
 *

View on GitHub (pinned to eafeac097b)

Solutions

  1. Wrap the update in an object: this.setState({count: 1})
  2. Use an updater function when the next state depends on the previous: this.setState(prev => ({count: prev.count + 1}))
  3. Pass null/undefined to intentionally bail out instead of a meaningless primitive

Example fix

// before
this.setState('loading');
this.setState(42);

// after
this.setState({status: 'loading'});
this.setState({count: 42});
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate partialState shape before calling setState
function safeSetState(component, partialState, callback) {
  const ok = partialState == null ||
    typeof partialState === 'object' ||
    typeof partialState === 'function';
  if (!ok) {
    console.warn('setState ignored non-object/function:', partialState);
    return;
  }
  component.setState(partialState, callback);
}

Type guard

const isSetStateArg = (v: unknown): v is object | Function | null | undefined =>
  v == null || typeof v === 'object' || typeof v === 'function';

Prevention

When it happens

Trigger: Calling this.setState('loading'), this.setState(true), this.setState(42), or this.setState(Symbol()) inside a class component; often a typo like setState(someStringVariable) intended as a key.

Common situations: Confusing setState with a key/value API (e.g. expecting setState('count', 1)); passing an unwrapped variable that is actually a primitive; copy-pasting from hook-style code where setCount(1) is valid.

Related errors


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