no-set-state-in-component-did-update
Disallows calling 'this.setState' in 'componentDidUpdate' outside functions such as callbacks.
Full Name in eslint-plugin-react-x
react-x/no-set-state-in-component-did-updateFull Name in @eslint-react/eslint-plugin
@eslint-react/no-set-state-in-component-did-updatePresets
x
recommended
recommended-typescript
recommended-type-checked
strict
strict-typescript
strict-type-checked
Rule Details
Updating the state after a component updates will trigger an additional render() call and can lead to property/layout thrashing or infinite loops.
The official React documentation permits calling setState immediately in componentDidUpdate when it is wrapped in a condition (e.g., comparing this.props to prevProps), so it does not run on every update — otherwise an unconditional call causes an infinite loop. Even so, it's best to avoid it when possible; the main legitimate case is measuring a DOM node (e.g., for modals and tooltips) before rendering something that depends on its size or position. This rule still reports such calls, so you can disable it selectively for those cases.
Examples
Calling setState directly in componentDidUpdate
// 🔴 Problem: Calling setState directly in componentDidUpdate triggers another render and can easily cause infinite loops or layout thrashing
import React from "react";
interface MyComponentProps {}
interface MyComponentState {
name: string;
}
class MyComponent extends React.Component<MyComponentProps, MyComponentState> {
componentDidUpdate() {
this.setState({ name: "John" });
// ^^^ Do not call `this.setState` in `componentDidUpdate` outside functions such as callbacks.
}
render() {
return <div>Hello {this.state.name}</div>;
}
}Responding to prop changes without extra state
If you need to perform side effects when props change, do so conditionally and avoid synchronous setState calls that trigger additional renders.
// 🟢 Recommended: Perform conditional side effects without synchronous setState
import React from "react";
interface MyComponentProps {
roomId: string;
}
interface MyComponentState {
serverUrl: string;
}
class ChatRoom extends React.Component<MyComponentProps, MyComponentState> {
state = {
serverUrl: "https://localhost:1234",
};
componentDidUpdate(prevProps: MyComponentProps) {
if (this.props.roomId !== prevProps.roomId) {
this.destroyConnection();
this.setupConnection(); // Side effect, not setState
}
}
componentWillUnmount() {
this.destroyConnection();
}
setupConnection() {
/* ... */
}
destroyConnection() {
/* ... */
}
render() {
return <div>Room: {this.props.roomId}</div>;
}
}Resources
Further Reading
See Also
react-x/no-set-state-in-component-did-mount
Disallows callingthis.setStateincomponentDidMountoutside functions such as callbacks.react-x/no-set-state-in-component-will-update
Disallows callingthis.setStateincomponentWillUpdateoutside functions such as callbacks.