Event bubbling in React refers to when the innermost component handles an event, and events bubble outwards. In React, the innermost element will first be able to handle the event, and then surrounding elements will then be able to handle it themselves.
In this article, we’ll go over how to best use event bubbling in React. We’ll see how it works, go through a few examples, and then use a few methods to modify the event bubbling property.
Let’s get started!
Event Bubbling Overview
Take the following code example:
function App() {
function outerHandle() {
console.log('outer')
}
function innerHandle() {
console.log('inner')
}
return (
<div onClick={outerHandle}>
<div onClick={innerHandle}>
Hello World
</div>
</div>
)
}
export default App;
When we run the code, we get the words “Hello World” rendered to the browser. When we click on it, the onClick events fire.
We get the following output in the console:
As we can see, the ‘inner’ got printed before the ‘outer’, because of event bubbling. The innermost component in this case is the inner <div>, so its event gets handled first (printing ‘inner’ to the console). After it does so, the outer <div> is allowed to handle the event, printing ‘outer’ to the console.
Event Bubbling vs. Event Capturing
With event bubbling, the event gets handled by the innermost component first, before getting passed to the outer components for their own handling. On the other hand, event capturing goes from the the outermost component and works its way inwards.
To illustrate this, here is the same example as the one we went through above, but utilizing event capturing instead.
function App() {
function outerHandle() {
console.log('outer')
}
function innerHandle() {
console.log('inner')
}
return (
<div onClickCapture={outerHandle}>
<div onClickCapture={innerHandle}>
Hello World
</div>
</div>
)
}
export default App;
As we can see, the example above uses ‘onClickCapture’ instead of ‘onClick’, telling React to use event capturing instead of event bubbling. We can see the results in the console:
We can see that ‘outer’ was printed before ‘inner’ this time, as we expected.
It’s important to be able to distinguish between methods for event bubbling and event capturing, as the results can be very different, despite the methods for either being similarly named.
Multiple Children within Parent
So far, we’ve seen examples where there is a single <div> nested within another. React event bubbling really shines when we have multiple children within the same parent element.
What we are then able to do is call specific functions when the event is handled by each of the children, and then call a general function in the parent element.
Here’s an example. We’ll first create a new functional component called ‘Child’ within a file ‘Child.js’:
function Child (props) {
function handleClick() {
console.log('this is ' + props.name)
}
return (
<div onClick={handleClick}>
{props.name}
</div>
)
}
export { Child }
The above component will render a name (specified in props) to the screen, and print out a statement with its name in it when clicked.
Now, in App.js:
import { Child } from './Child';
function App() {
function outerHandle() {
console.log('This is the parent.')
}
return (
<div onClick={outerHandle}>
<Child name='Child 1'/>
<Child name='Child 2'/>
<Child name='Child 3'/>
<Child name='Child 4'/>
</div>
)
}
export default App;
The above code renders four child components within a parent <div>. The div has a function ‘outerHandle()’ that gets called when it’s the parent’s turn to handle the onClick event.
Let’s see what happens when we click on the renderings in the console.
After clicking on each child element from top to bottom, we get:
As we can see, we get four different messages from each of the different child components, each followed by the exact same text from the parent element’s ‘outerHandle’ method.
The above example shows how we can use React’s event bubbling to generalize child components’ behavior when an event is triggered. We can see how having multiple children within a single parent could scale up to bigger applications where we’d want each child element to first perform its own unique event handling before passing on the event to the parent.
Event Propagation
Our examples so far have seemed pretty trivial. We understand that when we are using event bubbling, the events get handled by the innermost element first before being passed on to the outer elements one layer at a time.
One more important feature of event bubbling is that we can stop the propagation of the event at any time. For example, after the innermost element handles the event, we can specify that unlike the usual behavior we’d expect, outer components will not handle the event further.
To accomplish this, we use React’s event.stopPropogation().
The following example uses the same code from the previous example, with some changes in Child.js:
function Child (props) {
function handleClick(e) {
console.log('this is ' + props.name)
if ( props.name == 'Child 2' ) {
e.stopPropagation()
}
}
return (
<div onClick={handleClick}>
{props.name}
</div>
)
}
export { Child }
function Child (props) {
function handleClick(e) {
console.log('this is ' + props.name)
if ( props.name == 'Child 2' ) {
e.stopPropagation()
}
}
return (
<div onClick={handleClick}>
{props.name}
</div>
)
}
export { Child }
In the above code, we changed ‘handleClick()’ to take in the parameter e, which the event will automatically be passed in as. In addition to the console.log() we had from before, we’ve added an if statement.
If the child’s name is ‘Child 2’, we’ll call e.stopPropagation() to prevent the parent element from being able to handle the event. This means that the parent’s event handling method will not be called.
When we click on each child element from top to bottom, we get the following output to the console:
Notice how this time, there is no ‘This is the parent’ between Child 2 and Child 3. This is because Child 2 used stopPropagation() to prevent the parent element from executing its event handling method.
React event bubbling can be applied to much more complex structures of inner and outer elements. We can nest elements within elements nested within elements, and so on, and create complex event handling structures so that functions get called exactly as we’d like.
That’s it for this article! I hope you enjoyed learning how to use React’s event bubbling feature. Feel free to leave any questions or comments below.
💬 Leave a comment