はじめに
Reactを使っている上でe.persist()
について理解していなかったので、調べてまとめてみようと思います。
e.persist()
はonChange
などのコールバック関数内で使用し、イベントe
がpersist
関数を呼び出すという処理です。
基本的にonChange
などの中ではstate
を更新することが多いと思います。state
を更新する時にe.persist()
を読んでないと上手く値を取れないらしいから、ひとまず使っとくみたいな認識でした。
( 実際にはe.persist()
しなくても値取れることないですか?値取れるから呼び出すのサボったりしてないですか?僕はしてました。 )
ひとまず使っとけばええやろ精神から今回脱却しようと思います。e.persist()
をよく知らない方、ひとまず使ってる方は是非読んでいただけると嬉しいです!
結論
e.persist()
はReact 16以前のバージョンなら、ひとまず使っておけばOKです。
React17以降は全くもって不要です。
ドキュメントを読んでみる
イベントプーリングのドキュメント
ドキュメントを読んでみましょう。いきなり大事なこと書かれてました。
補足
イベントプーリング – React https://ja.reactjs.org/docs/legacy-event-pooling.html
このページの内容は React 16 以前および React Native にのみ関連します。
ウェブで使う React 17 ではイベントプーリングは使用されていません。
React17ではe.persist()
の記述は不要ということですね。(多分React17以降いらない)
イベントプーリング – React https://ja.reactjs.org/docs/legacy-event-pooling.html
SyntheticEvent
オブジェクトはプールされます。つまりSyntheticEvent
はイベントハンドラが呼び出された後に再利用され、すべてのプロパティが null にセットされます。
つまり、アプリ内でonChange
やonClick
した際に発行されるイベントオブジェクトは使いまわしているという事ですかね。
以前発行されたイベントから、直前に発行されたイベントに切り替わる時にnullが一時的にセットされ、
nullガード的な振る舞いをするのが、persist
関数という感じですかね。
イベントプーリング廃止の理由
ブログに残されていたので、読んでみましょう。
React 17 では「イベントプーリング」による最適化が取り除かれています。モダンブラウザではパフォーマンス向上にならず、経験のある React ユーザですらこの挙動に混乱していました
React v17.0 Release Candidate https://ja.reactjs.org/blog/2020/08/10/react-v17-rc.html#no-event-pooling
古いブラウザではメモリとかの都合上、オブジェクトを使い回していたとかなんですかね。
イベントプーリングによる効果はモダンブラウザでは意味がなく、むしろDXを低下させるからReact17以降廃止したっぽいですね。
ふたたび結論
React17以降なら必要なし。
React16以前はe.persist()
はひとまず呼び出しておけばいい。
雑談
特に面白味がない記事になってしまいましたね。persist
がどんな処理なのかまで言及すれば面白そうですが、さっと調べた感じ、コスパ悪そうだったので、諦めちゃいました。
イベントオブジェクトを使いまわしてるってことが新しく知れたので、まあいいでしょう。
自分でアプリ作る時とかも何かを使い回すとかキャッシュに残すってことは、やったりするのですが、
結構面倒ですよね。現在の状態が最新なのかとか気を使わなくてはですし。
そういう面倒を全部e.persist
に内包してたのは感心しますね。
ただ、必ず使わないと死ぬみたいな処理を他のエンジニアに書かせる設計は良くないと思います。なので、React17以降で廃止されたのは、めちゃくちゃ良いことだと思います。
この処理をしたいときはこの関数を絶対使ってね。みたいな実装はしないようにしましょう。
もし必要があるのであればhooksにまとめるなりした方が親切ですし、バグも起きなくなるので。
わからん殺しは優しくない上に誰も得しないですもんね。