カテゴリ: React 更新日: 2026/02/22

Reactでイベントバブリングとキャプチャリングを理解!初心者向けイベントハンドリング解説

イベントバブリングとキャプチャリングを理解しよう
イベントバブリングとキャプチャリングを理解しよう

先生と生徒の会話形式で理解しよう

生徒

「先生、Reactでボタンをクリックすると親のイベントも発火してしまいます。これはなぜですか?」

先生

「それはイベントバブリングが起きているからです。子要素のイベントが親要素に伝わっていく現象のことです。」

生徒

「イベントバブリングって聞きなれません。簡単に説明してもらえますか?」

先生

「簡単に言うと、水面に投げた小石の波紋のように、子要素のイベントが親要素やその上の要素まで順番に伝わる動きです。」

生徒

「じゃあキャプチャリングって何ですか?」

先生

「キャプチャリングはバブリングとは逆で、親要素から子要素へ順番にイベントを処理することです。」

生徒

「なるほど、ではReactでどう使うのか例を見せてください。」

先生

「では実際にコードで確認してみましょう。」

1. イベントバブリングの基本例

1. イベントバブリングの基本例
1. イベントバブリングの基本例

Reactでは子要素でクリックイベントが発生すると、自動的に親要素にもそのイベントが伝わります。これがイベントバブリングです。親要素と子要素両方で同じ処理をしたくない場合には、event.stopPropagation()を使ってバブリングを止めることができます。


import React from "react";

function App() {
  const handleParentClick = () => {
    alert("親要素がクリックされました");
  };

  const handleChildClick = (event) => {
    event.stopPropagation();
    alert("子要素がクリックされました");
  };

  return (
    <div onClick={handleParentClick} style={{ padding: "50px", backgroundColor: "#eee" }}>
      親要素
      <button onClick={handleChildClick}>子要素ボタン</button>
    </div>
  );
}

export default App;
(子要素ボタンをクリックすると親要素のアラートは表示されず、子要素のアラートだけが表示されます)

2. キャプチャリングの利用

2. キャプチャリングの利用
2. キャプチャリングの利用

通常、Reactのイベントはバブリングで伝わりますが、キャプチャリングを使うと親から順にイベントを処理できます。これを指定するには、onClickCaptureのように「Capture」を付けたイベントハンドラを使います。


import React from "react";

function App() {
  const handleParentCapture = () => {
    alert("キャプチャリング:親要素");
  };

  const handleChildClick = () => {
    alert("子要素クリック");
  };

  return (
    <div onClickCapture={handleParentCapture} style={{ padding: "50px", backgroundColor: "#cfc" }}>
      親要素
      <button onClick={handleChildClick}>子要素ボタン</button>
    </div>
  );
}

export default App;
(子要素ボタンをクリックすると、まず親要素のキャプチャリングアラートが表示され、その後子要素のアラートが表示されます)

3. バブリングとキャプチャリングの使い分け

3. バブリングとキャプチャリングの使い分け
3. バブリングとキャプチャリングの使い分け

バブリングは子要素で発生したイベントを親要素でも処理したいときに使います。逆に、キャプチャリングは親要素から先に処理を行い、子要素の処理を制御したい場合に便利です。状況に応じてonClickonClickCaptureを使い分けると、複雑なUIでも効率的にイベントを管理できます。

また、stopPropagationでバブリングを止めることもできるため、意図しないイベントの伝播を防ぐことができます。これにより、Reactアプリで親子関係のある要素のイベント制御を柔軟に行えます。

例えば、モーダルの背景クリックで閉じる処理を行う場合や、リスト項目のクリックで詳細を表示する場合など、イベントの伝播の理解は非常に重要です。

4. stopPropagationの注意点とよくある勘違い

4. stopPropagationの注意点とよくある勘違い
4. stopPropagationの注意点とよくある勘違い

event.stopPropagation()は、イベントバブリング(子から親へ伝わる流れ)を止めるために使います。ただし「クリック自体を無効にする」わけではなく、あくまで親要素へイベントが伝播しないようにするためのメソッドです。

そのため、子要素のonClickは通常通り実行されますし、同じ要素に別の処理があればそれも動きます。「親のクリックだけ止めたい」「意図しない親のイベント発火を防ぎたい」というケースで使うと効果的です。

また、親側でonClickCaptureを使っている場合、キャプチャリングは親→子の順で処理されるため、子要素側でstopPropagationを実行しても、親のキャプチャ処理はすでに走っている点に注意が必要です。イベントバブリングとキャプチャリングの順番を理解しておくと、Reactのイベントハンドリングで迷いにくくなります。

5. モーダルやメニューでのイベント伝播の活用例

5. モーダルやメニューでのイベント伝播の活用例
5. モーダルやメニューでのイベント伝播の活用例

ReactでよくあるUIとして、モーダルやドロップダウンメニューがあります。たとえば「背景をクリックしたらモーダルを閉じる」処理を親要素に置き、モーダル本体のクリックでは閉じないようにする、といった実装がよく行われます。

このとき、背景(親)にonClickを設定し、モーダル本体(子)でstopPropagationを使うと、モーダル内部をクリックしても背景クリック扱いにならず、意図しない閉じる動作を防げます。イベントバブリングを理解していると、こうした親子要素のクリック制御を自然に設計できます。

さらに、リスト項目のクリックで詳細画面へ遷移しつつ、項目内の削除ボタンだけは別処理にしたい場合なども、イベント伝播の制御が役立ちます。Reactのクリックイベントが親に伝わる仕組みを押さえることで、複雑な画面でも動作を安定させやすくなります。

6. Reactのイベントハンドラ命名と設計のコツ

6. Reactのイベントハンドラ命名と設計のコツ
6. Reactのイベントハンドラ命名と設計のコツ

イベントバブリングやキャプチャリングを扱う場面では、イベントハンドラの役割が増えるため、命名と設計が重要になります。たとえば親要素ならhandleParentClick、子要素ならhandleChildClickのように、どの要素の処理かが伝わる名前にすると読みやすくなります。

また、キャプチャリングを使う場合はhandleParentCaptureのように「Capture」を含めておくと、onClickとの違いが明確になります。ReactではonClickonClickCaptureが混在すると挙動の理解が難しくなるため、命名で意図が分かるだけでもトラブルを減らせます。

さらに、親子でクリック処理が関わるUIでは「親でまとめて処理したいのか」「子だけで完結させたいのか」を先に決めると整理しやすいです。イベントの伝播を前提に考えることで、Reactアプリのイベントハンドリングをスムーズに組み立てられます。

まとめ

まとめ
まとめ

今回の記事では、Reactにおけるイベントハンドリングの要である「イベントバブリング」と「キャプチャリング」について詳しく解説してきました。Web開発、特にReactのようなコンポーネントベースのライブラリを使用していると、意図しない場所でクリックイベントが発生したり、親要素の処理が走り出したりといった現象に必ず遭遇します。これらはブラウザの仕様である「イベント伝播(Event Propagation)」の仕組みによるものですが、正しく理解して制御することで、より洗練されたユーザーインターフェースを構築することが可能になります。

イベント伝播のメカニズムを振り返る

イベントが要素に到達し、そこから抜けていくまでには、大きく分けて3つのフェーズが存在します。

  • キャプチャリングフェーズ:イベントが最上位の要素(windowやdocument)からターゲット要素に向かって降りていく段階です。
  • ターゲットフェーズ:実際にイベントが発生した要素でイベントが発火する段階です。
  • バブリングフェーズ:イベントがターゲット要素から再び親要素、最上位要素へと昇っていく段階です。

Reactの標準的なイベント属性(onClickなど)は、このうち「バブリングフェーズ」で実行されます。逆に、親から順に処理を行いたい特殊なケースでは、onClickCaptureなどの「Capture」が付いた属性を利用することで、キャプチャリングフェーズでの処理が可能になります。

実践的なコードでの応用:イベントの停止

最も頻繁に利用されるテクニックは、event.stopPropagation()による伝播の停止です。例えば、リスト全体をクリックすると詳細ページへ飛ぶという設計の中で、そのリスト内にある「お気に入りボタン」だけは別の挙動をさせたい、といった場合に非常に有効です。


import React, { useState } from "react";

function EventStopExample() {
  const [log, setLog] = useState("");

  const handleParentClick = () => {
    setLog("親要素(カード全体)のイベントが発火しました。");
  };

  const handleChildClick = (e) => {
    // これを記述しないと、親要素のクリックイベントも動いてしまう
    e.stopPropagation();
    setLog("子要素(ボタン)のイベントが発火しました。伝播は止まっています。");
  };

  return (
    <div 
      onClick={handleParentClick} 
      style={{ 
        border: "2px solid #333", 
        padding: "20px", 
        borderRadius: "8px",
        cursor: "pointer",
        backgroundColor: "#f9f9f9"
      }}
    >
      <h3 className="fs-6">クリック可能なカード</h3>
      <p>カードのどこかをクリックしてみてください。</p>
      
      <button 
        onClick={handleChildClick}
        className="btn btn-primary"
      >
        ボタンだけをクリック
      </button>

      <div className="alert alert-secondary mt-3">
        ログ:{log}
      </div>
    </div>
  );
}

export default EventStopExample;
(カード内のボタンをクリックすると「子要素のイベントが発火しました」と表示されます。stopPropagationのおかげで、親カードのクリック処理は無視されます)

より高度な制御:キャプチャリングの活用シーン

日常的な開発でキャプチャリングを意識することは少ないかもしれませんが、特定の監視やログ収集、あるいは「子要素のいかなるクリックよりも先に親が介入したい」という場合には非常に強力なツールとなります。

例えば、アクセシビリティの向上や、特定の条件下で子要素の操作を一括で無効化したい場合などにonClickCaptureが役立ちます。Reactは仮想DOMを通じてこれらの標準的なブラウザイベントを「合成イベント(SyntheticEvent)」として最適化して提供しているため、ブラウザ間の差異を気にすることなく、一貫した実装ができるのが大きなメリットです。

最後に:設計の際のポイント

イベントのバブリングを利用することは、決して悪いことではありません。むしろ「イベントデリゲート(イベント委任)」という手法では、親要素で子要素のイベントを一括管理することでメモリ消費を抑え、パフォーマンスを向上させることができます。大切なのは、「今、イベントがどこから来てどこへ向かっているのか」を常に意識して、明示的にコードを書くことです。

Reactでの開発において、状態(State)の管理と同じくらい重要なのが、このイベントの管理です。コンポーネントが複雑になればなるほど、イベントの伝播を制する者がUIの挙動を制すると言っても過言ではありません。ぜひ、今回学んだバブリングとキャプチャリングを、皆さんのプロジェクトで活用してみてください。

先生と生徒の振り返り会話

生徒

「先生、ありがとうございました!イベントバブリングとキャプチャリングの違いが、図をイメージするように理解できました。特にevent.stopPropagation()が、波紋が広がるのを途中で止める防波堤のような役割なんだなって思いました。」

先生

「その例えは非常に分かりやすいですね!まさにその通りです。水面に投げた石の波紋(バブリング)を、必要ないところまで広げないように制御するのが、フロントエンドエンジニアの腕の見せ所ですよ。」

生徒

「実際にコードを書いてみると、onClickCaptureを使う場面は少なそうですが、親から先にチェックを入れたい時には便利そうですね。あと、Reactのドキュメントで『合成イベント』という言葉を見かけたのですが、これも関係ありますか?」

先生

「鋭いですね。Reactはブラウザ固有のイベントをそのまま使うのではなく、SyntheticEventという独自のラッパーで包んでいます。これによって、どのブラウザでも同じようにバブリングやキャプチャリングが動作するように保証されているんです。仕組みを知っておくと、デバッグの時に役立ちますよ。」

生徒

「なるほど、Reactが裏側で守ってくれているんですね。でも、まずは基本のonClickと、困ったときのstopPropagation、そして親から処理するonClickCaptureの3つをしっかり使い分けられるように練習してみます!」

先生

「素晴らしい意気込みです。特にモーダルウィンドウの作成や、複雑なフォームの実装ではこの知識が必須になります。もし挙動がおかしいな?と思ったら、まずは『今、イベントはバブリングしている最中かな?』と疑ってみる癖をつけてみてくださいね。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Reactでイベントバブリングとは何ですか?

イベントバブリングとは、Reactにおいて子要素で発生したクリックイベントなどが、親要素へと伝わっていく仕組みのことです。DOM構造が深くなると影響範囲が広がるため、注意が必要です。
カテゴリの一覧へ
新着記事
New1
React
Reactコンポーネントの再利用と分割を完全マスター!初心者でもわかるコンポーネント設計
New2
React
ReactでAxiosインターセプターの使い方を完全ガイド!初心者でもわかるリクエストとレスポンスの処理方法
New3
React
JSXの書き方!初心者でもわかるReactタグと属性の基本ルール解説
New4
React
ReactとDockerを使った開発環境構築の基本を徹底解説!初心者でもわかるReactとDockerの連携方法
人気記事
No.1
Java&Spring記事人気No1
React
ReactでonChangeイベントを使ってフォーム入力値を管理する方法を初心者向けに解説
No.2
Java&Spring記事人気No2
React
ReactとTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.3
Java&Spring記事人気No3
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!
No.7
Java&Spring記事人気No7
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.8
Java&Spring記事人気No8
React
Reactのフォーム処理でよくあるエラーと解決法を完全解説!初心者でも安心して学べるReact入門