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
- Define render as a normal prototype method: `render() { return ... }` inside the class body.
- If you prefer arrow functions, bind in the constructor instead (`this.render = this.render.bind(this)`) while keeping `render()` a prototype method.
- 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
- Always declare render as a regular method: `render() { ... }`, never as a class-property arrow function in observer components.
- Ensure every @observer class extends React.Component/PureComponent and implements render.
- Add a unit test that renders each observer class to catch missing/misdefined render early.
- Configure Babel/TS so class fields don't silently shadow prototype methods where this matters.
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
- The provided component class (${displayName}) has already be
- The componentWillReact life-cycle event is no longer support
- It is not allowed to use shouldComponentUpdate in observer b
- [mobx-react-lite] You are trying to use `observer` on a func
- [mobx-react] `observer(${displayName}).componentDidMount` mu
AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28).
Data as JSON: /api/errors/12725ed89b85f3ce.
Report an issue: GitHub.