这是一个基本组件。<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

当前回答

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

<Button onClick={(e)=> {e.stopPropagation(); yourFunction(someParam)}}>Delete</Button>

其他回答

这并不是100%理想的,但是如果在儿童->儿童时尚中传递道具太痛苦,或者创建Context. provider /Context。消费者只是为了这个目的),并且你正在处理另一个库,它有自己的处理程序,它在你的库之前运行,你也可以尝试:

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

据我所知,这件事。persist方法可以防止对象立即被扔回React的SyntheticEvent池。因此,在React中传递的事件在你到达它的时候实际上并不存在!这种情况发生在孙辈中,因为React处理内部的事情的方式是首先检查父级的SyntheticEvent处理程序(特别是如果父级有一个回调)。

只要你没有调用持久化,这将创建重要的内存继续创建事件,如onMouseMove(你没有创建某种Cookie Clicker游戏,如奶奶的饼干),这应该是完全没问题的!

另外请注意:通过偶尔阅读他们的GitHub,我们应该密切关注React的未来版本,因为他们可能最终会解决一些痛苦,因为他们似乎正在朝着在编译器/编译器中折叠React代码的方向发展。

如果希望发生嵌套元素中的操作而不是父元素中的操作,则可以从父元素的操作处理程序中检查目标的类型,然后根据该类型执行操作,也就是说,如果目标是嵌套元素,则不执行任何操作。否则两个处理程序都将被调用。

// Handler of the parent element. Let's assume the nested element is a checkbox
function handleSingleSelection(e) {
    if(e.target.type !== 'checkbox') {
        // We do not do anything from the 
        // parent handler if the target is a checkbox ( our nested element)
        // Note that the target will always be the nested element
        dispatch(lineSelectionSingle({ line }))
    }
}

我也有同样的问题。我发现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();  //  <------ Here is the magic
    this.props.onClick();
  }

  render() {
    return (
      <li onClick={this.handleClick}>
        {this.props.children}
      </li>       
    )
  }
}

DOM事件的顺序:捕获vs冒泡

事件的传播有两个阶段。这被称为“捕捉”和“冒泡”。

               | |                                   / \
---------------| |-----------------   ---------------| |-----------------
| element1     | |                |   | element1     | |                |
|   -----------| |-----------     |   |   -----------| |-----------     |
|   |element2  \ /          |     |   |   |element2  | |          |     |
|   -------------------------     |   |   -------------------------     |
|        Event CAPTURING          |   |        Event BUBBLING           |
-----------------------------------   -----------------------------------

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

// CAPTURING event
button.addEventListener('click', handleClick, true)

// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)

在React中,冒泡事件也是默认使用的。

// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>

// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>

让我们来看看我们的handleClick回调(React):

function handleClick(e) {
  // This will prevent any synthetic events from firing after this one
  e.stopPropagation()
}
function handleClick(e) {
  // This will set e.defaultPrevented to true
  // (for all synthetic events firing after this one)
  e.preventDefault()  
}

一个我在这里没有看到的替代方案

如果你在所有的事件中调用e.preventDefault(),你可以检查一个事件是否已经被处理,并防止它再次被处理:

handleEvent(e) {
  if (e.defaultPrevented) return  // Exits here if event has been handled
  e.preventDefault()

  // Perform whatever you need to here.
}

关于合成事件和本机事件的区别,请参阅React文档:https://reactjs.org/docs/events.html

解决这个问题的另一种方法是在子进程上设置onMouseEnter和onMouseLeave事件。(你的< li >标签) 当鼠标悬停在子进程上时,您可以设置一个特定的状态来停止父进程以执行onClick函数内容。 喜欢的东西:

class List extends React.Component {
  constructor(props) {
    super(props)
    this.state.overLi = false
  }

  handleClick() {
    // do something
  }

  render() {
    return (
      <ul
        onClick={(e) => {
          if (!this.state.overLi) {
            console.log("parent")
            this.handleClick()
          }
        }}
      >
        <li
          onClick={(e) => {
            console.log("child")
            // prevent default? prevent propagation?
            this.handleClick()
          }}
          onMouseEnter={() =>
            this.setState({
              overLi: true,
            })
          }
          onMouseLeave={() =>
            this.setState({
              overLi: false,
            })}
        ></li>
      </ul>
    )
  }
}

我已经搜索了很多,没有设法实现任何解决方案为我的上下文使用e.s stoppropagation ()