私の場合は子要素であるボタンを押した際に、親要素であるモーダルを表示させる処理が発火されてしまい、意図せずモーダルが出現しました。
このような親要素へイベントが伝わるのを防ぐために使われるのが、e.stopPropagation()というものです。
e.stopPropagation() は、JavaScriptのイベントオブジェクト(Event)のメソッドで、イベントの伝播(バブリング・キャプチャリング)を停止するためのものです。
イベント伝播とは
ブラウザのイベントは、次の順番で伝わります。
- キャプチャリング(親 → 子)
- ターゲット(対象要素)
- バブリング(子 → 親)
普段意識するのは主にバブリング(子から親へ伝わる)です。
主な役割
- 子要素で発生したイベントが親要素に伝わるのを止める
- UIの意図しない挙動(例:モーダルが開く)を防ぐ
- コンポーネントの責務を分離する
ただし、以下は止まりません。
- ブラウザのデフォルト動作(例:リンク遷移、フォーム送信)
preventDefaultとの違い
- stopPropagation():イベントの伝播を止める
- preventDefault():デフォルト動作を止める
例:
e.stopPropagation(); // 親にイベントを伝えない
e.preventDefault(); // リンク遷移などを止める
基本的な使用例
child.addEventListener('click', (e) => {
e.stopPropagation(); // 親への伝播を止める
console.log("子要素だけ処理");
});
この場合、親要素のクリックイベントは実行されません。
Reactでの使用例
const handleClick = (e) => {
e.stopPropagation();
console.log("子要素のみ処理");
};
return (
<div onClick={() => console.log("親クリック")}>
<button onClick={handleClick}>ボタン</button>
</div>
);
挙動:
- ボタンを押す → 子の処理のみ実行
- 親の onClick は実行されない
注意点
eventを受け取る必要がある
NG:
const handleClick = () => {
e.stopPropagation(); // eはundefined
};
OK:
const handleClick = (e) => {
e.stopPropagation();
};
eventを渡さないと動かない場合がある
NG:
onClick={() => handleClick()}
OK:
onClick={(e) => handleClick(e)}
または:
onClick={handleClick}
多用しすぎない
- 本来はイベント設計で解決すべきケースもある
- stopPropagationは「局所的に制御したいとき」に使うのがベスト