mobxjs/mobx · error

[mobx-react] class component (${displayName}) is missing `re

Error message

[mobx-react] class component (${displayName}) is missing `render` method.
`observer` requires `render` being a function defined on prototype.
`render = () => {}` or `render = function() {}` is not supported.

What it means

mobx-react's observer patches `prototype.render` to set up the tracking reaction, so `render` must be a regular function defined on the class prototype. If `prototype.render` is not a function — missing entirely, or defined as a class property/instance arrow function that observer cannot patch reliably — it throws with the display name and guidance.

Source

Thrown at packages/mobx-react/src/observerClass.ts:90

    if (componentClass["__proto__"] !== PureComponent) {
        if (!prototype.shouldComponentUpdate) {
            prototype.shouldComponentUpdate = observerSCU
        } else if (prototype.shouldComponentUpdate !== observerSCU) {
            // n.b. unequal check, instead of existence check, as @observer might be on superclass as well
            throw new Error(
                "It is not allowed to use shouldComponentUpdate in observer based components."
            )
        }
    }

    if (__DEV__) {
        Object.defineProperties(prototype, observablePropDescriptors)
    }

    const originalRender = prototype.render
    if (typeof originalRender !== "function") {
        const displayName = getDisplayName(componentClass)
        throw new Error(
            `[mobx-react] class component (${displayName}) is missing \`render\` method.` +
                `\n\`observer\` requires \`render\` being a function defined on prototype.` +
                `\n\`render = () => {}\` or \`render = function() {}\` is not supported.`
        )
    }

    prototype.render = function () {
        Object.defineProperty(this, "render", {
            // There is no safe way to replace render, therefore it's forbidden.
            configurable: false,
            writable: false,
            value: isUsingStaticRendering()
                ? originalRender
                : createReactiveRender.call(this, originalRender)
        })
        return this.render()
    }

View on GitHub (pinned to 01211a698b)

Solutions

  1. Define render as a normal prototype method: `render() { return ... }` inside the class body.
  2. If you prefer arrow functions, bind in the constructor instead (`this.render = this.render.bind(this)`) while keeping `render()` a prototype method.
  3. Check the class actually extends React.Component/PureComponent and that render isn't misspelled or deleted.

Example fix

// before
class View extends React.Component {
  render = () => <div>{this.props.value}</div>
}
export default observer(View) // throws

// after
class View extends React.Component {
  render() { return <div>{this.props.value}</div> }
}
export default observer(View)
Defensive patterns

Strategy: validation

Validate before calling

if (typeof MyClass.prototype.render !== 'function') {
  throw new Error('Class must define render as a prototype method (not an arrow-function field) before observer')
}

Type guard

const hasPrototypeRender = (c) => typeof c?.prototype?.render === 'function' &&
  Object.prototype.hasOwnProperty.call(c.prototype, 'render') &&
  !Object.getOwnPropertyDescriptor(c.prototype, 'render').value.toString().includes('=>')

Try / catch

try {
  Observed = observer(MyClass)
} catch (e) {
  if (String(e.message).includes('missing `render` method')) {
    // fix the class: convert render to a prototype method, then retry
  }
  throw e
}

Prevention

When it happens

Trigger: Forgetting to define a render method; defining `render = () => {...}` as a class instance property (arrow-function class field) or `render = function() {...}` as a field, so it is not a prototype method; a typo like `rendor` leaving prototype.render undefined.

Common situations: TS/Babel class-properties style where render is written as an arrow function field; refactor removing render accidentally; copying store classes that have no render and decorating them with @observer.

Related errors


AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28). Data as JSON: /api/errors/12725ed89b85f3ce. Report an issue: GitHub.