DEV Community

nakzyu
nakzyu

Posted on

React - Preventing Event Propagation from Parent Elements, Event Bubbling, Capturing, and Propagation

This topic is not directly related to React, but understanding Event Bubbling and Capturing in HTML and JS can be applied to React as well.

Suppose there is a component with a div tag as the parent and a button tag as the child rendered in the DOM, as shown below:

const Example = () => (
  <div
    onClick={(event) => {
      console.log("div clicked");
    }}
  >
    <button
      onClick={(event) => {
        console.log("button clicked");
      }}
    ></button>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Event Capturing and Bubbling

When the button is clicked, JS handles event propagation as follows:

Image description

1 Starting from the top-level Document, it looks for the target of the onClick event one step at a time.

This process of finding the target is called Event Capturing.

2 After finding the target, it goes back up to the top-level Document.

  • This process of going back up is called Event Bubbling.
  • While going back up, if the event registered on the element (the target, which is either the button, div, body, or html) that triggered the Event Capturing, then it triggers all corresponding events in order.
  • Since the button has an event corresponding to the onClick event, "button clicked" is outputted to the console.
  • As it goes up, the parent of the button, which is the div, also has an event corresponding to the onClick event, so "div clicked" is outputted to the console.
  • There is no more output because body and html do not have any registered event for onClick.

How to Prevent Console Output from the Div? - Event Propagation

Events occur during the Event Bubbling Phase. If you stop this bubbling, you can prevent the event from being executed. This is called Event Propagation.

You can execute propagation by calling event.stopPropagation().

const Example = () => (
  <div
    onClick={(event) => {
      console.log("div clicked");
    }}
  >
    <button
      onClick={(event) => {
        event.stopPropagation();
        console.log("button clicked");
      }}
    ></button>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

If you propagate the button's event like in the above example, the event will no longer bubble up, and the div's onClick event will not be triggered.

Top comments (0)