###Reactの合成イベント(SyntheticEvent )特性
- ブラウザのイベントハンドラーとReactのSyntheticEvent は別である
- SyntheticEventはPullingされる。
- SyntheticEvent再使用される。
- 全ての属性は呼び出し後に初期化される。
###実際にエラーを作てみましょう
export default function App() {
const syntheticEvent = (event) => { // 1.全ての属性は呼び出し後に初期化される。
setTimeout(() => {.
console.log(event.target.value); //2. 非同期でevent.target.valueを呼ぶと警告が発生する!!
}, 1000);
};
return (
<div className="App">
<input type="text" onChange={syntheticEvent} />
</div>
);
}
##警告発生
Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property >
target
on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event >around, use event.persist(). See https://fb.me/react-event-pooling for more information.
解決方法
#####1. event.persist()を追加する
export default function App() {
const syntheticEvent = (event) => {
event.persist() // 1. 警告が書いているメソッドを追加
setTimeout(() => {
console.log(event.target.value);
}, 1000);
};
return (
<div className="App">
<input type="text" onChange={syntheticEvent} />
</div>
);
}
補足
非同期処理の中でイベントのプロパティにアクセスしたい場合は、event.persist() をイベント> 内で呼び出す必要があります。これにより、合成イベントがイベントプールの対象から除外され、イベントへの参照をコードで保持できるようになります。
上のreactドキュメントはevent.persist()を利用する場合。
①. 合成イベントがイベントプールから除外される。
②. ①の理由で呼び出し後に初期化されない。
③. ②の理由で非同期の内部でもevet.target.valueの値が利用できる
event.persist()を利用する事は上の①の理由でオススメしない。
####2. event.target.valueの値をPrimitive(プリミティブ)値で取得
export default function App() {
const syntheticEvent = (event) => {
const value = event.target.value // 1.primitive値で取得
setTimeout(() => {
console.log(value); //2.警告は発生しない値を表示
}, 1000);
};
return (
<div className="App">
<input type="text" onChange={syntheticEvent} />
</div>
);
}
この方法でする事をオススメします。
合成イヴェントを除外しなくても利用できます。
結論
Reactの合成イベントを利用する時は非同期処理について注意が必要
setStateなども非同期で処理するので注意!
参考記事
https://ja.reactjs.org/docs/events.html#gatsby-focus-wrapper