mobxjs/mobx · error
It is not allowed to use shouldComponentUpdate in observer b
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.
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)
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
- The provided component class (${displayName}) has already be
- The componentWillReact life-cycle event is no longer support
- [mobx-react] class component (${displayName}) is missing `re
- [mobx-react] `observer(${displayName}).componentDidMount` mu
- [mobx-react-lite] You are trying to use `observer` on a func
AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28).
Data as JSON: /api/errors/6b9ac4579f16a797.
Report an issue: GitHub.