To stop event propagation in React, call e.stopPropagation() inside the event handler. This prevents the event from bubbling up to parent handlers, so only the handler on the element you want reacts. The method lives on the event object React passes to the handler.
Why propagation needs stopping
Bubbling is usually helpful, but it can run a parent handler at the wrong time. A card that collapses when clicked might also collapse when a button inside it is clicked, because both handlers fire.
function Card() {
return (
<div onClick={() => alert("Card collapsed")}>
<button onClick={() => alert("Saved")}>Save</button>
</div>
);
}Click Save and both alerts appear. The button's own handler runs first, then the click bubbles to the div and collapses the card, which is not what the button intended.
Nested elements share the same click. Without a stop, an inner action triggers the outer action too, and the user sees two effects from one press.
Call stopPropagation
Stop the bubble by calling e.stopPropagation() in the button's handler. The parent div then never sees the click.
function Card() {
return (
<div onClick={() => alert("Card collapsed")}>
<button onClick={(e) => {
e.stopPropagation();
alert("Saved");
}}>Save</button>
</div>
);
}Click Save now shows only the saved alert. The card stays open because the click never reaches the div's handler. Other handlers on the same element would still run, but nothing above it fires.
React applies the method to its own event object, so the effect is limited to this one event and does not change future clicks. The card behaves like an independent control, and clicking its inner button no longer collapses it.
stopPropagation is not preventDefault
These two methods solve different problems and are easy to confuse. e.stopPropagation() stops the event from bubbling up the tree. e.preventDefault() stops the browser's default action, like a form reload.
They are independent, and calling one does not call the other. A link that should log a click but not navigate needs both: preventDefault stops the navigation, and stopPropagation keeps an outer handler from also firing.
When not to stop propagation
Stopping propagation can hide the event from handlers that legitimately need it, like an analytics listener near the root. Stop it only when a parent handler should not run for this specific action, not as a default habit.
Stop the event only at the boundary you own, and let everything above it keep working normally. If the parent logic is hard to trace, have the child call a passed handler instead of relying on the bubble.
What to learn next
The two directions events travel are covered in event bubbling and capturing. For stopping the page from reloading, the prevent default guide walks through the other half of the pair.
Rune AI
Key Insights
- Call e.stopPropagation() inside the child handler.
- The parent handler no longer fires for that event.
- It does not stop the browser's default action.
- preventDefault and stopPropagation are independent.
- Prefer a real button so default behavior is already correct.
Frequently Asked Questions
What does e.stopPropagation() do in React?
Does stopPropagation also prevent default behavior?
Will handlers on the same element still run?
Conclusion
Call e.stopPropagation() inside a handler to keep the event from bubbling to parents. It solves accidental parent handlers, but it does not touch the browser's default action.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.