React does not always propagate component state changes to the underlying DOM elements immediately. If you modify the state during an already
ongoing update cycle, the change may be delayed until the next update. React tries to keep this.state
in sync with what is currently in
the DOM, so you should never directly modify this.state
yourself. Instead, use the asynchronous setState
method instead,
which allows React to properly manage the current state, trigger the new update cycle, or batch the updates together if necessary.
Note that setState()
is a request to change the state, not an immediate update. For example, if multiple components are
changing the state in response to a user event, React will wait until the event handler has finished executing and then render all the changes in a
single update. In other cases, the updates may be executed one at a time, so you should never make assumptions about how the component state will
change in response to your request.
If your next state is a function of the current state, you should pass an updater function to the setState()
that will give you access
to the correct component state at the time of the execution.
The only place where you should directly modify the state is during the component initialization in a constructor function.
class MyComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
incrementCount() {
this.state.count++; // Noncompliant: direct mutation of state object
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
To fix this code use setState()
method instead of directly mutating the state.
class MyComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
incrementCount() {
this.setState(prevState => ({
count: prevState.count + 1
}));
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}