Reactjs 如何防止嵌套的React组件中的事件在单击时冒泡?

Reactjs 如何防止嵌套的React组件中的事件在单击时冒泡?,reactjs,onclick,event-propagation,Reactjs,Onclick,Event Propagation,这是一个基本组件。和都有onClick功能。我只想在上单击一次即可点火,而不是。我怎样才能做到这一点 我已经使用了e.preventDefault()、e.stopPropagation(),但没有任何效果 class List extends React.Component { constructor(props) { super(props); } handleClick() { // do something } render() { re

这是一个基本组件。
  • 都有onClick功能。我只想在
  • 上单击一次即可点火,而不是
    。我怎样才能做到这一点

    我已经使用了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
    
    类列表扩展了React.Component{
    建造师(道具){
    超级(道具);
    }
    handleClick(){
    //做点什么
    }
    render(){
    返回(
    
      { console.log('parent'); 这个。handleClick(); }} >
    • { console.log('child'); //防止默认?防止传播? 这个。handleClick(); }} >
    ) } } //=>父母 //=>孩子
    我也有同样的问题。我发现停止广播确实有效。我会将列表项拆分为一个单独的组件,如下所示:

    类列表扩展了React.Component{
    handleClick=e=>{
    //做点什么
    }
    render(){
    返回(
    
      项目
    ) } } 类ListItem扩展了React.Component{ handleClick=e=>{
    e、 停止传播();//React将事件委派与文档上的单个事件侦听器一起用于冒泡的事件,如本例中的“单击”,这意味着不可能停止传播;在React中与真实事件交互时,真实事件已经传播。React的合成事件上的StopperPagation是可能的,因为React处理传播对内部合成事件的处理

    stopPropagation: function(e){
        e.stopPropagation();
        e.nativeEvent.stopImmediatePropagation();
    }
    

    执行此操作的新方法简单得多,可以节省一些时间!只需将事件传递到原始的click处理程序中,并调用
    preventDefault();


    我在获取
    event.stopPropagation()
    时遇到问题。如果您也这样做,请尝试将其移动到click handler函数的顶部,这是我阻止事件冒泡所需的操作。函数示例:

      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;
        }
      }
    

    这并不是100%理想,但如果在儿童->儿童时尚中传递
    道具
    ,或者创建
    上下文。提供者
    /
    上下文。消费者
    只是为了这个目的),并且您正在处理另一个在您前面运行自己处理程序的库,那么您也可以尝试:

       function myHandler(e) { 
            e.persist(); 
            e.nativeEvent.stopImmediatePropagation();
            e.stopPropagation(); 
       }
    
    据我所知,
    event.persist
    方法可防止对象立即被抛出React的
    SyntheticEvent
    池。因此,React中传递的
    事件在您获取它时实际上并不存在!由于React处理事物的方式,这种情况会在孙子辈中发生首先在内部向下检查父级以查找
    SyntheticEvent
    处理程序(尤其是在父级有回调的情况下)

    只要你没有调用
    persist
    来创建一些可以创建大量内存的事件,比如
    onMouseMove
    (并且你没有创建像奶奶的Cookies这样的Cookie点击器游戏),就应该可以了


    另外请注意:通过偶尔阅读他们的GitHub,我们应该关注React的未来版本,因为它们可能最终解决一些问题,因为它们似乎要在编译器/transpiler中生成折叠React代码。

    您可以通过检查事件的目标来避免事件冒泡。
    例如,如果您将输入嵌套到div元素中,其中包含click事件的处理程序,并且您不想处理它,那么在单击输入时,您只需将
    事件传递给处理程序。target
    ,并根据target的属性执行check is处理程序。
    例如,您可以检查
    是否(target.localName==“input”){return}

    因此,这是一种按照DOM事件的顺序“避免”处理程序执行的方法:捕获与冒泡 事件如何传播有两个阶段。这两个阶段被称为“捕获”和“冒泡”

                   | |                                   / \
    ---------------| |-----------------   ---------------| |-----------------
    | element1     | |                |   | element1     | |                |
    |   -----------| |-----------     |   |   -----------| |-----------     |
    |   |element2  \ /          |     |   |   |element2  | |          |     |
    |   -------------------------     |   |   -------------------------     |
    |        Event CAPTURING          |   |        Event BUBBLING           |
    -----------------------------------   -----------------------------------
    
    捕获阶段首先发生,然后是冒泡阶段。当您使用常规DOM api注册事件时,默认情况下,这些事件将是冒泡阶段的一部分,但这可以在创建事件时指定

    //捕获事件
    按钮。addEventListener('click',handleClick,true)
    //冒泡事件
    按钮。addEventListener('click',handleClick,false)
    按钮。addEventListener('click',handleClick)
    
    在React中,冒泡事件也是默认情况下使用的事件

    // handleClick is a BUBBLING (synthetic) event
    <button onClick={handleClick}></button>
    
    // handleClick is a CAPTURING (synthetic) event
    <button onClickCapture={handleClick}></button>
    
    功能手柄点击(e){
    //这会将e.defaultPrevented设置为true
    //(对于在此事件之后触发的所有合成事件)
    e、 预防默认值()
    }
    
    我在这里没有提到的另一种选择 如果在所有事件中调用e.preventDefault(),则可以检查事件是否已被处理,并防止再次处理:

    handleEvent(e){
    if(e.defaultPrevented)return//如果事件已被处理,则在此处退出
    e、 预防默认值()
    //在这里你需要做什么就做什么。
    }
    

    有关合成事件和本机事件之间的区别,请参阅React文档:

    这是一种简单的方法,可以防止单击事件向前移动到下一个组件,然后调用函数

    <Button onClick={(e)=> {e.stopPropagation(); yourFunction(someParam)}}>Delete</Button>
    
    {e.stopPropagation();yourFunction(someParam)}>Delete
    
    我也有同样的问题,不应该
    这个.props.handleClick()
    列表项中
    组件是
    这个.道具.点击
    ?除了stopPropogation之外还有其他方法吗?在本机组件上,比如
    上,如果需要将参数传递给handleClick,该怎么办?这不是回答了错误的问题吗?OP要求列表项来处理事件。解决方案有列表来处理它。(除非我误解了什么。)超级有用..停止播放()本身工作不正常这
    <Button onClick={(e)=> {e.stopPropagation(); yourFunction(someParam)}}>Delete</Button>