web-dev-qa-db-fra.com

ReactJS SyntheticEvent stopPropagation () ne fonctionne qu'avec les événements React?

J'essaie d'utiliser event.stopPropagation () dans un composant ReactJS pour empêcher un événement click de se propager et de déclencher un événement click associé à JQuery dans du code hérité, mais il semble que stopPropagation () de React arrête uniquement la propagation aux événements également attaché dans React, et stopPropagation () de JQuery n'arrête pas la propagation aux événements attachés avec React.

Est-il possible de faire en sorte que stopPropagation () agisse sur tous ces événements? J'ai écrit un simple JSFiddle pour démontrer ces comportements:

/** @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();
    });
});
109
lofiinterstate

React utilise la délégation d'événements avec un écouteur d'événement unique sur document pour les événements qui apparaissent comme "clic" dans cet exemple, ce qui signifie que l'arrêt de la propagation n'est pas possible. l'événement réel s'est déjà propagé au moment où vous interagissez avec lui dans React. stopPropagation sur l'événement synthétique de React est possible car React gère la propagation des événements synthétiques en interne.

Travailler JSFiddle avec les corrections d’en bas.

Réagir arrêter la propagation sur l'événement jQuery

Utilisez Event.stopImmediatePropagation pour éviter que vos autres écouteurs (jQuery dans ce cas) de la racine soient appelés. Il est pris en charge dans les navigateurs IE9 + et modernes.

_stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
},
_
  • Avertissement: les auditeurs sont appelés dans l'ordre dans lequel ils sont liés. React doit être initialisé avant tout autre code (jQuery ici) pour que cela fonctionne.

jQuery Stop Propagation sur React Event

Votre code jQuery utilise également la délégation d'événements, ce qui signifie que l'appel de stopPropagation dans le gestionnaire n'arrête rien; l'événement a déjà été propagé à document et l'auditeur de React sera déclenché.

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

Pour empêcher la propagation au-delà de l'élément, l'auditeur doit être lié à l'élément lui-même:

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

Edit (2016/01/14): Clarifié que la délégation n'est nécessairement utilisée que pour les événements en bulle. Pour plus de détails sur la gestion des événements, les sources de React ont des commentaires descriptifs: ReactBrowserEventEmitter.js .

145
Ross Allen

C'est encore un moment intéressant:

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

Utilisez cette construction, si votre fonction est encapsulée par tag

6
Roman Lemaro

J'ai pu résoudre ce problème en ajoutant les éléments suivants à mon composant:

componentDidMount() {
  ReactDOM.findDOMNode(this).addEventListener('click', (event) => {
    event.stopPropagation();
  }, false);
}
6
senornestor

J'ai rencontré ce problème hier et j'ai donc créé une solution conviviale pour React.

Découvrez react-native-listener . Cela fonctionne très bien jusqu'à présent. Commentaires appréciés.

6
Erik R.

Il est à noter (de this issue ) que si vous attachez des événements à document, e.stopPropagation() ne vous aidera pas. Pour contourner le problème, vous pouvez utiliser window.addEventListener() au lieu de document.addEventListener, puis event.stopPropagation() empêchera l’événement de se propager à la fenêtre.

5
Jim Nielsen

Mise à jour: vous pouvez maintenant <Elem onClick={ proxy => proxy.stopPropagation() } />

1
Eric Hodonsky