Event Bubbling and Capturing in React
February 12, 2022
By default, React event handlers are triggered by an event in the bubbling phase. This means that events are handled by the innermost element and propagated to outer elements. However, in some cases, you may want to trigger event handlers in the capturing phase. In React, a click event is triggered using capture with onClickCapture
.
<button onClickCapture={handleClick}>Click me</button>
You can append Capture
to any event name to register an event handler for the capture phase.
<button
onFocusCapture={handleFocus}
onBlurCapture={handleBlur}
onTouchEndCapture={handleTouchEnd}
onTouchStartCapture={handleTouchStart}>
A few example event handlers using capture
</button>
Event Propagation
Event propagation refers to the process of an event being handled by an element and then traversing through the other elements of the DOM. When a click event is fired on a button, unless steps are taken to stop propagation, other elements in the DOM will also fire any registered click events. The process, or direction, of how that event propagates is determined by the event phase registered by the event listener.
Bubbling
When an event that is registered for the bubbling phase is triggered on an element, the event is handled by the target element and propagated to its parent element. If the parent element has an event handler registered for the bubbling phase, it will be triggered and the event will continue to propagate up the DOM.
<div onClick={() => alert("outer")} className="outer">
<div onClick={() => alert("inner")} className="inner">
click
</div>
</div>
In this example, the click event is registered on the bubbling phase as that is the default for all React event handlers. The inner div
will fire it’s event handler first and then the outer div
’s onClick
will fire.
Capturing
When we register an event handler on the capturing phase, the event is handled by the ancestor elements it and traverses downwards to the target element. In the following example, the click event is handled by the parent element first reslting in the alert
firing for the outer div
first.
<div onClickCapture={() => alert("outer")} className="outer">
<div onClickCapture={() => alert("inner")} className="inner">
click
</div>
</div>
Stop Propagation
To stop further propagation of the event in both capturing and bubbling phases, React utilizes the same stopPropagation
interface as the browser. In the following example, the click event is handled first by the target element (because it is registered on the bubbling phase with onClick
) and further propagation is halted.
<div onClick={() => alert("outer")}>
<div
onClick={(e) => {
e.stopPropagation();
alert("outer element event handler will not fire");
}}
>
click
</div>
</div>