componentDidMount runs right after the first render. Calling setState there renders the component a second time before the user sees anything, so every mount costs two renders. Put the value in the initial state if you already know it.
A setState in a callback inside componentDidMount is allowed by default, because it runs later, when a request finishes or an event fires.
The rule reports nothing if settings.react.version ([lint.settings.react] in bunfig.toml, or settings in an ESLint config) is 16.3 or later, or if it's "detect" and the installed version is 16.3 or later.
Configure
Off by default. To turn it on:
[lint.rules]
"react/no-did-mount-set-state" = "error" # or "warn"
Every option, set to its default. The ones that are commented out are unset by default.
[lint.rules]
"react/no-did-mount-set-state" = [
"error",
# "disallow-in-func",
]
Examples
Reported:
class Profile extends React.Component {
componentDidMount() {
this.setState({ name: this.props.name.toUpperCase() });
}
}
Not reported:
class Profile extends React.Component {
state = { name: this.props.name.toUpperCase() };
componentDidMount() {
loadUser(this.props.id).then(user => {
this.setState({ user });
});
}
}
Options
| Option | What it does |
|---|---|
"disallow-in-func" | Also report setState in a function inside componentDidMount. |
class Profile extends React.Component {
componentDidMount() {
loadUser(this.props.id).then(user => {
this.setState({ user });
});
}
}
When not to use it
Measuring the DOM needs this pattern. For example, a tooltip must render once before you can read its size and store the position. React flushes that second render before the browser paints.