ReactJS SyntheticEvent stopPropagation () работает только с событиями React?

Я пытаюсь использовать event.это происходит() в ReactJS компонент, чтобы остановить события click от бурлят и вызывая событие click, которое было прикреплено с помощью jQuery в legacy код, но кажется, что Реакт это происходит() только останавливает распространение на мероприятиях также содержится в реакции, и это происходит в jQuery() не останавливает распространение на мероприятия, связанные с реагировать.

есть ли способ заставить stopPropagation () работать через эти события? Я написал простой JSFiddle для продемонстрируйте такое поведение:

http://jsfiddle.net/7LEDT/3/

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

5 ответов


React использует делегирование событий с одним прослушивателем событий на document для событий, которые пузырь, как "нажмите" в этом примере, что означает, что остановить распространение невозможно; реальное событие уже распространилось к тому времени, когда вы взаимодействуете с ним в React. stopPropagation на синтетическом событии React возможно, потому что React обрабатывает распространение синтетических событий внутри.

работа JSFiddle с исправлениями снизу: http://jsfiddle.net/7LEDT/6/

реагировать остановить распространение на jQuery Event

использовать Event.stopImmediatePropagation чтобы предотвратить вызов ваших других (jQuery в этом случае) слушателей в корне. Он поддерживается в IE9+ и современных браузерах.

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
},
  • нюанс: слушатели вызываются в том порядке, в котором они связаны. React должен быть инициализирован перед другим кодом (jQuery здесь) для этого работа.

jQuery остановить распространение на React Event

ваш код jQuery также использует делегирование событий, что означает вызов stopPropagation в обработчике ничего не останавливает; событие уже распространилось на document, и слушатель React будет запущен.

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

чтобы предотвратить распространение за пределы элемента, прослушиватель должен быть привязан к самому элементу:

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

изменить (2016/01/14): разъяснены эта делегация обязательно используется только для событий, которые пузырь. Для получения дополнительной информации об обработке событий Источник React имеет описательные комментарии: https://github.com/facebook/react/blob/3b96650e39ddda5ba49245713ef16dbc52d25e9e/src/renderers/dom/client/ReactBrowserEventEmitter.js#L23


я смог решить эту проблему, добавив в свой компонент следующее:

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

Я столкнулся с этой проблемой вчера, поэтому я создал React-friendly решение.

проверить реагировать родной-слушатель. Пока все работает очень хорошо. Обратная связь ценится.


это все еще один интересный момент:

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

использовать эту конструкцию, если ваша функция обернута тегом


Update: теперь вы можете <Elem onClick={ proxy => proxy.stopPropagation() } />