[javascript] ReactJS SyntheticEvent stopPropagation ()은 React 이벤트에서만 작동합니까?

ReactJS 구성 요소 내에서 event.stopPropagation ()을 사용하여 클릭 이벤트가 버블 링되는 것을 막고 레거시 코드에서 JQuery와 함께 첨부 된 클릭 이벤트를 트리거하려고하는데 React의 stopPropagation ()이 이벤트로의 전파 만 중지하는 것 같습니다. 또한 React에 첨부되어 있으며 JQuery의 stopPropagation ()은 React로 첨부 된 이벤트에 대한 전파를 중지하지 않습니다.

이러한 이벤트에서 stopPropagation ()이 작동하도록하는 방법이 있습니까? 이러한 동작을 보여주기 위해 간단한 JSFiddle 을 작성했습니다 .

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



답변

React는 document이 예제에서 ‘click’과 같이 버블 링되는 이벤트 에 대해 단일 이벤트 리스너가있는 이벤트 위임을 사용합니다 . 이는 전파를 중지 할 수 없음을 의미합니다. 실제 이벤트는 React에서 상호 작용할 때 이미 전파되었습니다. stopPropagationReact의 합성 이벤트는 React가 내부적으로 합성 이벤트의 전파를 처리하기 때문에 가능합니다.

아래에서 수정 한 JSFiddle 작업 .

jQuery 이벤트에 대한 반응 중지 전파

Event.stopImmediatePropagation루트의 다른 리스너 (이 경우 jQuery)가 호출되지 않도록 방지하는 데 사용 합니다. IE9 + 및 최신 브라우저에서 지원됩니다.

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
},
  • 경고 : 리스너는 바인딩 된 순서대로 호출됩니다. 이것이 작동하려면 다른 코드 (여기에서는 jQuery)보다 먼저 React를 초기화해야합니다.

React 이벤트에서 jQuery 중지 전파

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의 소스에 ReactBrowserEventEmitter.js 라는 설명 주석이 있습니다.


답변

워스 (에서 주목 이 문제 는 이벤트를 부착하는 경우 있음) document, e.stopPropagation()도움이 될 수 없습니다. 해결 방법으로 window.addEventListener()대신을 사용할 수 있습니다 document.addEventListener. 그러면 event.stopPropagation()이벤트가 창으로 전파되지 않습니다.


답변

여전히 한 번의 흥미 진진한 순간입니다.

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

함수가 태그로 래핑 된 경우이 구성을 사용합니다.


답변

내 구성 요소에 다음을 추가하여이 문제를 해결할 수있었습니다.

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


답변

어제이 문제가 발생하여 React 친화적 인 솔루션을 만들었습니다.

react-native-listener를 확인하세요 . 지금까지 매우 잘 작동하고 있습니다. 피드백에 감사드립니다.


답변

(가)에서 문서 반응 : 아래의 이벤트 핸들러가되어 트리거 이벤트가 버블 링 단계에서 . 캡처 단계에 대한 이벤트 핸들러를 등록하려면 Capture를 추가하십시오 . (강조 추가됨)

당신이 당신의 반작용 코드에서 클릭 이벤트 리스너가 있고 버블에 원하지 않는 경우에, 나는 당신이하고 싶은 것은 사용하는 것입니다 생각 onClickCapture대신 onClick. 그런 다음 이벤트를 핸들러에 전달하고 event.nativeEvent.stopPropagation()네이티브 이벤트가 바닐라 JS 이벤트 리스너 (또는 반응하지 않는 모든 것)로 버블 링되지 않도록합니다.


답변

업데이트 : 이제 <Elem onClick={ proxy => proxy.stopPropagation() } />