ReactではsetStateは即座に反映されない


ReactではsetStateで変更された内容はどうやら、renderされるまで反映されないらしい。
試しに以下のコードを試してみる。

class SetStateSample extends React.Component {
constructor(props) {
super(props)
this.state = {
val: ""
}
}
  handleClick() {
this.setState({val: "test"})
alert(this.state.val) // ""
}
render() {
return (
<h1 onClick={this.handleClick.bind(this)}}>{this.state.val}</h1>
)
}
}

上の例ではsetState前の値がalertにより表示される。
そのため、初回のalertでは初期値が表示される。
alertの時点でthis.state.valの値を正しく取得したい場合は以下のようにhandleClickを修正する。

handleClick() {
var new_val = "test"
this.setState({val: new_val})
alert(new_val) // "test"
}

つまり変数に入れてalertに入れるだけ。
これで想定したとおりの処理になる。

setState直後にstateが更新されない原因

React公式ページに以下の通りの記載がある。
https://ja.reactjs.org/docs/faq-state.html

setState 呼び出しは非同期です。呼び出し直後から this.state が新しい値を反映することを期待しないでください。もし現在の state に基づいた値を計算する必要がある場合は、オブジェクトの代わりに更新関数を渡してください。

https://ja.reactjs.org/docs/faq-state.html

setStateの呼び出しが非同期なので、setState直後には反映されていなかったんですね。
仮に現在のstateをもとに新しいstateに更新する場合は以下のように記載しましょう。

  handleClick() {
this.setState((state) =>
return { val: state.val + "test" }
});
}