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.
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:
window to the target element.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.
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.
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."
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.
GlobalClickListener component or add an onClick to your main App container.SearchBar component, ensure that clicking the input field does not trigger the global click listener that clears the search.e.stopPropagation() inside the search input's click handler to prevent the bubbling that would trigger the container's reset logic.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.preventDefault() and stopPropagation():
preventDefault() stops the browser's default behavior (like a form submitting or a link navigating).stopPropagation() stops the event from traveling to parent elements.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.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.
Learn to master the useEffect dependency array to control exactly when your side effects run. Avoid infinite loops and optimize your React components today.
Event Bubbling and Propagation
Polishing the UI
Finalizing the Movie Browser
Review of Component Lifecycle
Review of State Management
Building a Modal Component
Introduction to PropTypes
Performance Optimization Basics
Handling Browser History
Working with LocalStorage
Building a Favorites List
Handling Media in React
Introduction to Testing
Debugging React Apps
Deployment Basics
Using External Libraries
Advanced