reactjs-React阻止事件在cli上的嵌套组件中冒泡

这是一个基本组成部分。 <ul><li>都具有onClick功能。 我只希望触发<li>的onClick,而不希望<ul>。如何实现此目标?

我玩过e.preventDefault(),e.stopPropagation()都无济于事。

class List extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    // do something
  }

  render() {

    return (
      <ul 
        onClick={(e) => {
          console.log('parent');
          this.handleClick();
        }}
      >
        <li 
          onClick={(e) => {
            console.log('child');
            // prevent default? prevent propagation?
            this.handleClick();
          }}
        >
        </li>       
      </ul>
    )
  }
}

// => parent
// => child
dmwong2268 asked 2019-10-06T04:58:05Z
5个解决方案
86 votes

我遇到过同样的问题。 我发现stopPropagation确实有效。 我将列表项拆分为一个单独的组件,如下所示:

class List extends React.Component {
  handleClick = e => {
    // do something
  }

  render() {
    return (
      <ul onClick={this.handleClick}>
        <ListItem onClick={this.handleClick}>Item</ListItem> 
      </ul>
    )
  }
}

class ListItem extends React.Component {
  handleClick = e => {
    e.stopPropagation();
    this.props.onClick();
  }

  render() {
    return (
      <li onClick={this.handleClick}>
        {this.props.children}
      </li>       
    )
  }
}
Will Stone answered 2019-10-06T04:58:21Z
38 votes

React使用事件委派和文档上的单个事件侦听器来处理冒泡的事件,如本例中的“ click”,这意味着无法停止传播; 当您在React中与真实事件互动时,真实事件已经传播了。 由于React在内部处理合成事件的传播,因此有可能对React的合成事件进行stopPropagation。

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
}
Priyanshu Chauhan answered 2019-10-06T04:58:47Z
0 votes

我在使event.stopPropagation()工作时遇到问题。 如果您也这样做,请尝试将其移至单击处理程序函数的顶部,这是我阻止事件冒泡所需的操作。 示例功能:

  toggleFilter(e) {
    e.stopPropagation(); // If moved to the end of the function, will not work
    let target = e.target;
    let i = 10; // Sanity breaker

    while(true) {
      if (--i === 0) { return; }
      if (target.classList.contains("filter")) {
        target.classList.toggle("active");
        break;
      }
      target = target.parentNode;
    }
  }
Nenotlep answered 2019-10-06T04:59:12Z
0 votes

这不是100%理想的,但是如果要以小朋友的身份传承persist->以儿童的方式创建或为此目的创建onMouseMove/event实在是太痛苦了,那么您正在处理的是另一个拥有它自己的图书馆 它在您之前运行的处理程序,您也可以尝试:

   function myHandler(e) { 
        e.persist(); 
        e.nativeEvent.stopImmediatePropagation();
        e.stopPropagation(); 
   }

据我所知,persist方法可防止将对象立即扔回React的onMouseMove池中。 因此,因此,在您获得React时实际上不存在传递给它的event! 这是在子孙中发生的,这是因为React首先通过在向下检查父项来检查SyntheticEvent处理程序(特别是如果父项具有回调)来内部处理React事物的方式。

只要您没有在会创建大量内存以继续创建事件的东西(例如onMouseMove)上调用persist(并且您没有在创建类似祖母Cookie的Cookie Clicker游戏),那应该就可以了!

还要注意:从偶尔阅读他们的GitHub来看,我们应该对React的未来版本保持警惕,因为他们最终可能会解决一些麻烦,因为他们似乎打算在编译器/编译器中折叠React代码。

rob2d answered 2019-10-06T05:00:03Z
-2 votes

这样做的新方法要简单得多,并且可以节省您一些时间! 只需将事件传递到原始点击处理程序中,然后致电preventDefault();

clickHandler(e){
    e.preventDefault();
    //Your functionality here
}
Austin Rowe answered 2019-10-06T05:00:31Z
translate from https://stackoverflow.com:/questions/38619981/react-prevent-event-bubbling-in-nested-components-on-click