I understand that React tutorials and documentation warn in no uncertain terms that state should not be directly mutated and that everything should go through setState
It surprises me that non of the current answers talk about pure/memo components. These components only re-render when a change in one of the props is detected.
Say you mutate state directly and pass, not the value, but the over coupling object to the component below. This object still has the same reference as the previous object, meaning that pure/memo components wont re-render, even though you mutated one of the properties.
Since you don't always know what type of component you are working with when importing them from libraries, this is yet another reason to stick the non-mutating rule.
Here is an example of this behaviour in action (using R.evolve to simplify creating a copy and updating nested content):
class App extends React.Component {
state = {some: {rather: {deeply: {nested: {stuff: 1}}}}};
mutatingIncrement = () => {
this.state.some.rather.deeply.nested.stuff++;
this.setState({});
}
nonMutatingIncrement = () => {
this.setState(R.evolve(
{some: {rather: {deeply: {nested: {stuff: n => n + 1}}}}}
));
}
render() {
return
Pure Component:
Normal Component:
;
}
}
const CounterDisplay = (props) => (
Counter value: {props.some.rather.deeply.nested.stuff}
);
const PureCounterDisplay = React.memo(CounterDisplay);
ReactDOM.render( , document.querySelector("#root"));