1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React】 合成イベント(SyntheticEvent) を利用する時注意点

Last updated at Posted at 2020-10-17

###Reactの合成イベント(SyntheticEvent )特性

  1. ブラウザのイベントハンドラーとReactのSyntheticEvent は別である
  2. SyntheticEventはPullingされる。
  3. SyntheticEvent再使用される。
  4. 全ての属性は呼び出し後に初期化される。

###実際にエラーを作てみましょう


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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?