ReactJS SyntheticEvent stopPropagation () only works with React events?

I am trying to use event.stopPropagation () in a ReactJS component to stop a click event popup and trigger a click event that was attached with JQuery in legacy code, but it seems that React stopPropagation () only stops propagating to events also attached in React, and JQuery stopPropagation () does not stop propagation for React related events.

Is there a way to make stopPropagation () work through these events? I wrote a simple JSFiddle to demonstrate this behavior:

/** @jsx React.DOM */ var Propagation = React.createClass({ alert: function(){ alert('React Alert'); }, stopPropagation: function(e){ e.stopPropagation(); }, render: function(){ return ( <div> <div onClick={this.alert}> <a href="#" onClick={this.stopPropagation}>React Stop Propagation on React Event</a> </div> <div className="alert"> <a href="#" onClick={this.stopPropagation}>React Stop Propagation on JQuery Event</a> </div> <div onClick={this.alert}> <a href="#" className="stop-propagation">JQuery Stop Propagation on React Event</a> </div> <div className="alert"> <a href="#" className="stop-propagation">JQuery Stop Propagation on JQuery Event</a> </div> </div> ); } }); React.renderComponent(<Propagation />, document.body); $(function(){ $(document).on('click', '.alert', function(e){ alert('Jquery Alert'); }); $(document).on('click', '.stop-propagation', function(e){ e.stopPropagation(); }); }); 
+110
javascript jquery reactjs
Jun 25 '14 at 18:10
source share
7 answers

React uses event delegation with a single event listener per document for events that pop up, such as a โ€œclickโ€ in this example, which means stopping propagation is not possible; the real event is already spreading by the time you interact with it in React. stopPropagation in a React artificial event is possible because React handles the propagation of artificial events on its own.

JSFiddle work with corrections from below.

Respond to the propagation of a stop signal at a jQuery event

Use Event.stopImmediatePropagation to prevent other listeners (in this case jQuery) from being called in the root directory. It is supported in IE9 + and modern browsers.

 stopPropagation: function(e){ e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); }, 
  • Caution: listeners are called in the order in which they are connected. React must be initialized before other code (here jQuery) for this to work.

jQuery Stop React Propagation

Your jQuery code also uses event delegation, which means that calling stopPropagation in the handler does not stop anything; the event is already passed to document , and the React Listener will be fired.

 // Listener bound to 'document', event delegation $(document).on('click', '.stop-propagation', function(e){ e.stopPropagation(); }); 

To prevent propagation outside the element, the listener should be attached to the element itself:

 // Listener bound to '.stop-propagation', no delegation $('.stop-propagation').on('click', function(e){ e.stopPropagation(); }); 

Edit (2016/01/14): Clarified that delegation is necessarily used only for events that pop up. For more information on event handling, the React source has descriptive comments: ReactBrowserEventEmitter.js .

+146
Jun 26 '14 at 3:19
source share

I ran into this problem yesterday, so I created a React-friendly solution.

Check out the responsive native listener . So far, everything is working very well. Feedback is welcome.

+6
Sep 03 '14 at 6:40
source share

I managed to solve this problem by adding the following to my component:

 componentDidMount() { ReactDOM.findDOMNode(this).addEventListener('click', (event) => { event.stopPropagation(); }, false); } 
+6
Nov 10 '16 at 7:41
source share

This is another interesting point:

 ev.preventDefault() ev.stopPropagation(); ev.nativeEvent.stopImmediatePropagation(); 

Use this construct if your function is tagged

+6
Nov 28 '17 at 10:02
source share

It is worth noting (from this problem ) that if you attach events to document , e.stopPropagation() will not help. As a workaround, you can use window.addEventListener() instead of document.addEventListener , then event.stopPropagation() will stop the event propagating to the window.

+6
Oct 18 '18 at 17:04 on
source share

Update: now you can <Elem onClick={ proxy => proxy.stopPropagation() } />

+1
Feb 17 '17 at 22:23
source share

From the React documentation : The following event handlers are triggered by an event in the bubble phase . To register an event handler for the capture phase, add Capture . (selection added)

If your React code has a click event listener, and you don't want it to pop up, I think you need to use onClickCapture instead of onClick . Then you must pass the event to the handler and execute event.nativeEvent.stopPropagation() to prevent the native event from jumping to a regular JS event listener (or anything that does not respond).

+1
Sep 25 '19 at 2:06
source share



All Articles