Mastering Event Bubbling and Propagation in React
Learn how event bubbling works in React, how to stop unwanted propagation, and how to manage global vs. local events in your movie-browser app.
Previously in this course, we looked at Handling Click Events: Interactive Components in React. While we successfully triggered functions, we didn't account for what happens when events overlap. Today, we’re digging into how events travel through the DOM and how you can control that flow.
Understanding Event Propagation
When you click a button inside a div, you aren't just clicking the button. You are clicking the button, its parent div, the section wrapping that, and so on, all the way up to the document object. This process is called event propagation.
In the browser, this happens in three phases:
- Capturing Phase: The event travels down from the
windowto the target element. - Target Phase: The event hits the specific element you clicked.
- Bubbling Phase: The event "bubbles" back up from the target to the root.
React primarily hooks into the bubbling phase. When you attach an onClick to a component, React listens for that event as it bubbles up to the root of your application. Understanding this is critical because, in a complex UI like our movie browser, you might have a "Favorite" button inside a "Movie Card" that is itself clickable.
Why Bubbling Matters
Imagine your MovieCard has an onClick handler that opens the movie details, and inside that card, you have a "Delete" button. If you click the "Delete" button, you don't want the movie details to open—you only want the delete action to fire.
Without intervention, the click on the "Delete" button bubbles up to the MovieCard, triggering both events. This is a classic source of bugs in UI development.
Stopping Propagation
To prevent an event from moving further up the tree, you use the stopPropagation() method available on the event object.
Let’s update our MovieCard component to handle this interaction cleanly:
JSXfunction MovieCard({ title, onDelete, onClick }) { const handleInternalClick = (e) => { // Stop the event from reaching the MovieCard's onClick e.stopPropagation(); onDelete(); }; return ( <div className="movie-card" onClick={onClick}> <h3>{title}</h3> <button onClick={handleInternalClick}>Delete Movie</button> </div> ); }
By calling e.stopPropagation(), we tell the browser: "The event stops here. Do not notify any parent components."
Hands-on Exercise: The "Click-Away" Challenge
In our movie browser project, let's implement a feature where clicking anywhere on the screen (except the search bar) clears the current search results.
- Create a
GlobalClickListenercomponent or add anonClickto your mainAppcontainer. - In your
SearchBarcomponent, ensure that clicking the input field does not trigger the global click listener that clears the search. - Use
e.stopPropagation()inside the search input's click handler to prevent the bubbling that would trigger the container's reset logic.
Common Pitfalls
- Overusing
stopPropagation(): Don't use it unless you have to. It makes your code harder to debug because it breaks the expected flow of events for other developers (or even analytics tracking scripts) listening at the document level. - Confusing
preventDefault()andstopPropagation():preventDefault()stops the browser's default behavior (like a form submitting or a link navigating).stopPropagation()stops the event from traveling to parent elements.
- React's SyntheticEvent: Remember that the event object you receive in React is a
SyntheticEvent—a cross-browser wrapper around the native browser event. It behaves like the native event, but it's important to know it's a React-specific implementation. For more on how these event systems interact with the browser, check out our guide on Preventing DOM-based XSS: A Guide for Modern JavaScript Apps to see why controlling event sinks is a security best practice.
Recap
Event bubbling is the default behavior where events propagate from child to parent. In React, we manage this flow using the stopPropagation() method on the event object. Use this tool sparingly to ensure your UI interactions are predictable, especially when nesting clickable elements within your movie cards.
Up next: We'll take this knowledge of events and state to create a more complex UI interaction: Building a Movie Filter Toggle.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.