no-did-mount-set-state
no-did-mount-set-state rule
Prevent calling setState in componentDidMount. This rule is part of eslint-plugin-react-features.
Quick Summary
| Aspect | Details |
|---|---|
| Severity | Warning (performance) |
| Auto-Fix | ❌ No (requires refactoring) |
| Category | React |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | React class components |
Rule Details
Calling setState immediately in componentDidMount causes an additional render cycle. Initial state should be set in the constructor or derived from props.
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 🔄 Double render | Performance degradation | Set state in constructor |
| 🐛 Wasted cycles | Unnecessary DOM updates | Use derived state |
| 🔍 Flicker | UI may flash between states | Initialize state properly |
Examples
❌ Incorrect
class UserProfile extends React.Component {
state = { user: null };
componentDidMount() {
// BAD: Immediate setState causes extra render
this.setState({ loading: true });
// This is also problematic
this.setState({
windowWidth: window.innerWidth
});
}
}✅ Correct
class UserProfile extends React.Component {
// GOOD: initial state is set up front, not in a second render
state = { user: null, windowWidth: window.innerWidth };
componentDidMount() {
// GOOD: setState in a callback runs after the data arrives
fetchUser(this.props.id).then((user) => this.setState({ user }));
}
}The rule reports a component's own this.setState(…) (also this['setState']) that runs synchronously in componentDidMount — declared as a method, an arrow property or a quoted key — on a class that extends React's Component / PureComponent, however it is imported. A call inside a callback (a promise handler, a timer) runs later and is not reported; neither is another object's setState (store.setState(…)).
Configuration Examples
Basic Usage
{
rules: {
'react-features/no-did-mount-set-state': 'warn'
}
}Related Rules
no-did-update-set-state- Similar for componentDidUpdatereact-class-to-hooks- Migrate to hooks
Further Reading
- componentDidMount - React docs
- State Initialization - Constructor patterns
Known False Negatives
setStatereached through another method:componentDidMount() { this.load(); }whereloadcallsthis.setStatesynchronously is not followed.- An alias of
this:const self = this; self.setState(...)is not read as the component'ssetState. createReactClasscomponents are not covered; only classes that extend React'sComponent/PureComponent.
Not reported by design: setState inside a callback (fetchData().then(...), a timer), which runs after mount.
Use this rule
npm install -D oxlint-plugin-react-features{ "jsPlugins": ["oxlint-plugin-react-features"], "rules": { "react-features/no-did-mount-set-state": "error" }}import { defineConfig } from 'vite-plus';export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-react-features'], rules: { 'react-features/no-did-mount-set-state': 'error', }, },});oxlint-plugin-react-features re-exports eslint-plugin-react-features/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.
Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.