バブリング(イベントの伝播)について

バブリング(イベントの伝播)について

投稿日: 2024年11月17日

学習振り返り
要約
  • バブリングは、特定の要素のイベントが親要素に伝播する現象で、意図しない動作を引き起こすことがある。
  • イベントの伝播を防ぐためには、子要素のイベントハンドラ内でe.stopPropagation()を呼び出す必要がある。
  • 親と子のコンポーネントが分離している場合、デバッグが難しくなるため、イベントの出力を確認する作業が有効である。

はじめに

毎日お疲れさまです。

バブリングってご存じですか?私は知らないまま先週くらいまで来てて挙動がおかしいで色々調べるとバブリングのせいだと知り、厄介な存在だと感じました。

でも対策は簡単。知ってるか知らないかで時間溶かすかどうかが決まってくると思うので書くことにしました。

バブリング

特定の要素でイベントが発生した時に、その要素だけでイベントが発生するのではなくその要素の親要素へイベントが伝搬していき、親要素でも同じイベントが発生してしまう現象のことです。

イベントの伝播とも言います。

今思えば、あれはオリジナルアプリ作り始めて間もない頃、子要素のonclickでモーダルを開く処理をしているのに、開かないなんでって苦しんで、親要素のonclickでモーダル閉じる処理をしていたからだったことがありました。

あぁあれか・・となりました。

コード例

"use client";
import React from "react";

export const Bubbring: React.FC = () => {
  // 親要素のクリックイベントハンドラ
  const handleParentClick = (e: React.MouseEvent<HTMLDivElement>) => {
    alert("親要素がクリックされました!");
  };

  // 子要素のクリックイベントハンドラ
  const handleChildClick = (e: React.MouseEvent<HTMLDivElement>) => {
    alert("子要素がクリックされました!");
  };

  return (
    <div
      onClick={handleParentClick}
      className="flex size-full justify-center pt-64"
    >
      <div onClick={handleChildClick} className="">
        子要素
      </div>
    </div>
  );
};

こんな感じのコードは普通ないと思いますがあったとします。

クリックします。

子要素をクリックしたんですけど、OKを押すと

親要素まで反応します。これがバブリング(イベントの伝播)です。

対策

e.stopPropagation();

を追加します。


具体的に、追加した例です。

"use client";
import React from "react";

export const Bubbring: React.FC = () => {
  // 親要素のクリックイベントハンドラ
  const handleParentClick = (e: React.MouseEvent<HTMLDivElement>) => {
    alert("親要素がクリックされました!");
  };

  // 子要素のクリックイベントハンドラ
  const handleChildClick = (e: React.MouseEvent<HTMLDivElement>) => {
    e.stopPropagation();
    alert("子要素がクリックされました!");
  };

  return (
    <div
      onClick={handleParentClick}
      className="flex size-full justify-center pt-64"
    >
      <div onClick={handleChildClick} className="">
        子要素
      </div>
    </div>
  );
};

これで子要素のイベントは親要素に伝播せず、子要素のイベントのみ発火させることが出来ます。

おわりに

知ってたらなんてことないんですけど、知らないとドツボにハマります・・

私はハマった側の人です。身代わりにハマっておいたのでこれ読んだ人はハマらないでください。

今回の例のような単純なコードであればわかりやすいのですが、親と子のコンポーネントが別になっていたりするとパッと見ではわからないので厄介です。

私は一回すべてのイベントで発火する関数にconsoleで関数名出力して、どこをクリックしたらどこが発火しているか確認していきました。

そうしないとわからない。自分で書いたけどわからない。エディター上で追っていくより脳死でいけて早いと思いそうしました。地道な作業ですが嫌いじゃないです。

明日は月曜日。一週間頑張りましょう!!

おやすみなさい🎵

シェア!

Threads
user
吉本茜
山口在住/二児の母/育休中
Loading...
記事一覧に戻る
Threads
0