mobxjs/mobx · error
It is not allowed to use shouldComponentUpdate in observer…
Error message
It is not allowed to use shouldComponentUpdate in observer based components.
What it means
In observer class components, mobx-react installs its own `observerSCU` as `shouldComponentUpdate` to control re-rendering based on the observer reaction. A user-defined SCU would conflict with (and defeat) that mechanism, so if an existing SCU differs from observerSCU (and the class isn't a PureComponent), the wrap is rejected.
Solutions
- Remove your custom `shouldComponentUpdate` and rely on the observer's fine-grained tracking, which only re-renders on observed data changes.
- If SCU logic must remain, drop `observer` for that component and use explicit `<Observer>` regions for observable access instead.
- If conditional rendering is needed, gate it inside `render` (e.g. compare props there) or use React.memo-equivalent props checks in a parent.
Example fix
// before
class Row extends React.Component {
shouldComponentUpdate(nextProps) { return nextProps.id !== this.props.id }
render() { return <div>{this.props.item.name}</div> }
}
export default observer(Row) // throws
// after
class Row extends React.Component {
render() { return <div>{this.props.item.name}</div> }
}
export default observer(Row) Defensive patterns
Strategy: validation
Validate before calling
if (typeof MyClass.prototype.shouldComponentUpdate === 'function' &&
MyClass.prototype.shouldComponentUpdate.name !== 'observerSCU') {
throw new Error('Remove custom shouldComponentUpdate before applying observer')
} Type guard
const hasCustomScu = (c) => typeof c?.prototype?.shouldComponentUpdate === 'function' && c.prototype.shouldComponentUpdate.name !== 'observerSCU'
Try / catch
try {
Observed = observer(MyClass)
} catch (e) {
if (String(e.message).includes('shouldComponentUpdate')) {
// remove custom SCU or drop observer; cannot auto-fix safely
}
throw e
} Prevention
- Rely on observer's tracking instead of manual shouldComponentUpdate optimizations.
- If custom SCU is required, use <Observer> regions rather than wrapping the whole class.
- Code-review new @observer classes for presence of shouldComponentUpdate.
- Remember PureComponent is exempt; if you must keep SCU semantics, restructure accordingly.
When it happens
Trigger: Defining `shouldComponentUpdate` on a class and then applying `observer` (the symbol check lets an inherited observerSCU pass, but any custom SCU throws); extending PureComponent is exempt, anything else with custom SCU is not.
Common situations: Hand-optimized shouldComponentUpdate implementations from pre-observer code being combined with @observer; copying performance-tuned class components into an observer-based codebase.
Related errors
- [mobx-react] class component
- The componentWillReact life-cycle event is no longer…
- The provided component class
- [mobx-react] `observer
- [mobx-react] It seems that a re-rendering of a React…
AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28).
Data as JSON: /api/errors/6b9ac4579f16a797.
Report an issue: GitHub.
Appendix: source
Thrown at packages/mobx-react/src/observerClass.ts:77
if (componentClass[isMobXReactObserverSymbol]) {
const displayName = getDisplayName(componentClass)
throw new Error(
`The provided component class (${displayName}) has already been declared as an observer component.`
)
} else {
componentClass[isMobXReactObserverSymbol] = true
}
if (prototype.componentWillReact) {
throw new Error("The componentWillReact life-cycle event is no longer supported")
}
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.`
)
}View on GitHub (pinned to 01211a698b)