Imagine this code:
class App extends React.Component {
state = {
name: "george",
counter: 1
};
onClick() {
this.setState({
counter: 123,
name: this.state.name + this.state.counter
});
}
render() {
return (
<div
className="App"
onClick={() => {
this.onClick();
}}
>
<h1>Hello CodeSandbox</h1>
<h2>{this.state.name}</h2>
<h2>{this.state.counter}</h2>
</div>
);
}
}
If I click on the div
the output is:
george1
123
You can see that value of state.name
is george1
, which contains value of counter
which was current at the time onClick
was called. The state.counter
value itself has fresh value though.
How is this explained? Because if I do this instead:
onClick() {
this.setState({
counter: 123
});
setTimeout(() => {
this.setState({
name: this.state.name + this.state.counter
});
}, 1000);
}
Now output is
george123
123
It is same code basically but with different timing.
So what explains this behavior? Why in the first case it has current value of this.state.counter
(at the time of click) embedded in this.state.name
? And in the second case not?
Demo.
I know if I want to have old value of counter
embedded in the this.state.name
, and update this.state.counter
, I could also do this:
onClick() {
this.setState({ // even safer to use functional setState here
name: this.state.name + this.state.counter
}, ()=>{
this.setState({ // and here
counter:123
})
});
}
Is it safer than No1 approach (result is same)?