React イベントハンドリング・ガイド

ボタンをクリックしたときに、ウェブページ全体がリロードされてしまいますか?入力中にインプットボックスの状態(state)が更新されませんか?Reactでイベントを正しく扱えていないと、このような問題に直面することがあります。

イベントハンドリングとは、クリック、送信(submit)、変更(change)といったユーザーのアクションをキャプチャし、それらに反応することを指します。ReactはSyntheticEventと呼ばれるシステムを使用しています。これにより、Chrome、Safari、Firefoxといったすべてのブラウザでコードが同じように動作することが保証されます。

HTMLとReactのイベントの主な違い:

  • ネーミング:ReactではcamelCaseを使用します。onclickの代わりにonClickを使用してください。
  • ハンドラー:Reactでは関数の参照を渡します。文字列の代わりに波括弧(curly braces)を使用してください。
  • 防止:ブラウザのデフォルトの動作を停止させるには、常に event.preventDefault() を呼び出してください。

Reactのイベント処理の仕組み:

Reactはすべてのノードにリスナーをアタッチするわけではありません。「イベント委譲(Event Delegation)」を使用しています。ルート要素に単一のリスナーをアタッチすることで、メモリを節約し、パフォーマンスを向上させています。

よく使われるパターン:

  • クリックカウンター:ユーザーがボタンをクリックしたときに、関数を使用してstateを更新します。
  • フォームのハンドリング:event.target.nameevent.target.value を使用して、1つの関数で複数の入力フィールドを更新します。ページのリロードを防ぐために、フォーム送信時には必ず event.preventDefault() を使用してください。
  • 引数の渡し方:関数にIDを渡す必要がある場合は、アロー関数を使用してください。onClick={() => handleDelete(id)} と記述します。onClick={handleDelete(id)} と書くと、レンダリング中に即座に実行されてしまうため、避けてください。

次のような間違いを避けましょう:

  • 無限ループ:onClick 属性の中で関数を直接呼び出さないでください。これによりレンダリング中にstateの更新がトリガーされ、さらなるレンダリングが発生してしまいます。
  • 未定義のイベント:preventDefault() を呼び出す必要がある場合は、関数の定義に必ず event パラメータを含めてください。
  • メモリリーク:useEffect フック内で window.addEventListener のような手動のリスナーを追加した場合は、必ずクリーンアップ関数内でそれらを削除してください。

パフォーマンスのためのベストプラクティス:

  • リストが非常に大きい場合、.map() ループの中で新しい関数を作成するのは避けましょう。
  • 子コンポーネントにハンドラーを渡すときは、useCallback フックを使用してください。
  • アプリケーションの速度を維持するために、カスタムイベントリスナーは適切にクリーンアップしてください。

イベントをマスターすることは、インタラクティブなReactアプリケーションを構築するための鍵となります。

出典: https://dev.to/banti_kevat_8e2d123bb7994/react-me-events-handling-complete-guide-2p69