Reactでイベントコールバックのevent
オブジェクトに非同期でアクセスしようとするとエラーが出て怒られる。例えば、setState
の第二引数のコールバック内でevent
を参照しようとした時とか。
function clickHandler(event) {
this.setState({
foo: 'bar'
}, function () {
console.log(event.target.value); // error
});
}
なぜ参照できないか
ReactのドキュメントのEvent poolingに書いてあった。
The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.
簡単に説明すると、event
オブジェクトはReactによってSyntheticEvent
オブジェクトとしてラップされていて、パフォーマンスのために使いまわしてますよ。その関係で、イベントコールバックが実行され終わったら全てのプロパティをnull
にするから、非同期ではアクセスできませんよ、ということらしい。
解決策
これもドキュメントの同じ項に書かれている。
If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.
非同期でアクセスしたかったらevent.persist()
使ってくれ、と書かれている。なのでイベントコールバックの中で呼んであげれば非同期でevent
を参照することができる。
function clickHandler(event) {
event.persist();
this.setState({
foo: 'bar'
}, function () {
console.log(event.target.value); // ok
});
}