Repository navigation
Events propagate to nested components after stopPropagation() #1691
Description
Activity
@lrowe Prop_o_gation should be Prop_a_gation
- changed the title
[-]Events propagate to nested components after stopPropogation()[/-][+]Events propagate to nested components after stopPropagation()[/+]on Jun 14, 2014 Thanks @sompylasar, spelling fixed.
- added a commit that references this issue
on Jun 16, 2014 Hi there, it's been around 1.5 years passed, any plan on this issue? There are several cases in our team that we need to prevent the event bubbling of inner components. The workaround for us is painful: to drill down the target element and adding
addEventListenerto stop propagation there, then we have to care about the clean up, remove the listener when unmount.Not really, unfortunately. We don't have a good model for how events for nested trees should interact. Synthetic events and native events are two different concepts – for example, a native
keyupevent could result in a syntheticonChangeevent – but if you callpreventDefaulton theonChangeevent, should that prevent thekeyup? We dispatch the native event to each render tree and form the synthetic events separately in each tree right now, which we'd probably need to change to fix this properly. I'm afraid that any short-term solution here would be a patch that solves only a few cases and makes the code harder to reason about; we probably need a holistic rethinking of this problem to make a good solution here, and it's not something that we encounter very much because we're much more focused on React in a single render tree.For the record, I ran into this problem without doing anything exotic.
I've got a CRUD-style entity list table where each row has an onClick handler to "choose" the entity the row represents. But in one of the row's cells, there are control buttons with their own onClick handlers.
Now when I click on one of the buttons under the table row, the table row's onClick gets triggered before the button's!
I tried circumventing the problem by setting up a native browser event for the button component, but now any click anywhere seems to trigger just about everything on the page, even though I'm calling all the stop propagation methods I could find.
How can this still be a problem after two years? Why does React hijack event handling to begin with?
Reacted by Rigotti, Vinay, Maarten van Meersbergen, shishir arora, Toby Abel, Sofiène Djebali, Eric Hartford, Librae, Q, Laura Knight and 9 moreReacted by Alasdair, Q and NullGetting the same problem. I'm in a somewhat exotic environment though (overloading Gmail via a Chrome Extension), but the event propagation should stop all the same. I'm sure there was a good reason for hijacking the event system and creating SyntheticEvents, but this kinda takes away from something I really like about React (the fact that it always has a "top-hatch" to let you plug-n-play it in any environment).
Hi, I have a parent div and a child div, both handle onClick. If the mouse is on the child, I am calling event.stopPropogation but it is not working... This works fine in regular html. but not in react.
I have same problem. And I used a third-party component, Which means binding vanila event and then stop propagation is not feasible.
I have the same problem.
Sad
Reacted by Alasdair, sokka, vikasraj789, Tucker, Emil Valeev, Null, Mayank Chauhan and Renato Gama... same problem here... this is really annoying.
Is there a plan to fix this issue in the next version of React?
Reacted by Никита, Luke Griffiths, SHEN Lin and NullI stumbled accross this aswell. really annoying. @spicyj, any news?
It seems react-dropzone is also suffering from this one.
Portals introduced in React 16 let you unite several DOM trees into a single conceptual React tree. If I understand correctly, this should help address the original problem described in the post, as event bubbling works respects the React hierarchy in portals.
As @sophiebits noted in #1691 (comment), it is not clear what a generic fix would be like. Comments like “+1” and “Sad” don’t bring us closer to solving that problem.
I am closing this issue as I believe a reasonable workaround (portals) exists in React 16. Libraries providing modals should migrate to using portals.
If you are experiencing this problem but have a different use case, please file a new issue and describe it in more detail, preferably with an example. Unfortunately most other comments in this thread are too brief or lacking details.
Reacted by Vivek Iyer, Will Klein, Edward Njoroge, Samuel Cooper, Mohsin and SHEN LinReacted by Tucker, hmziq, Null, Mayank Chauhan and crimson968We're fixing a subset of these problems in React 17 — by moving native React event listeners from
documentto the root. Portals are still recommended if you use one copy of React though.If you want to try it:
https://reactjs.org/blog/2020/08/10/react-v17-rc.html- added a commit that references this issue
on May 15, 2024
We're using react-bootstrap modals in a site with full page rendering, so we have nested React rendering. As of d853c85 events are propagated to ancestors, but calls to
event.stopPropagation()on the inner component hierarchy are not respected by the outer component hierarchy.Complicating matters, the SyntheticEvent is created afresh for dispatch to each component hierarchy and there is no stoppedPropagation equivalent to
nativeEvent.defaultPreventedto be called in the SyntheticEvent constructor. So even ifforEachEventDispatch(EventPluginUtils.js) checkedevent.isPropagationStopped()in the single callback case, it would still return false.Tracking the propagationStopped status through a return value of
ReactEventEmitter.handleTopLevellooks tricky too givenEventPluginHub.extractEventsmay map a single nativeEvent to multiple synthetic events.The easiest fix may just be to set a custom property on the nativeEvent object in
SyntheticEvent.stopPropagationto check in the constructor, then checkevent.isPropagationStopped()in the single callback case offorEachEventDispatch.