React:通过嵌套组件冒泡的事件

kap*_*psi 26 javascript events reactjs

假设我有这样的嵌套组件:

<root />
  <comp1 />
    <comp2 />
      <target id={this.props.id}>
        <div>click me</div>
Run Code Online (Sandbox Code Playgroud)

我想点击目标在root上运行一个函数:

//on root component
this.action = function(id){}
Run Code Online (Sandbox Code Playgroud)

我是否需要在链中的每个组件上手动设置属性,就像在React教程示例中一样?的jsfiddle

<root />
  <comp1 clickHandler={this.action}/>
    <comp2 clickHandler={this.clickHandler}/>
      <target id={this.props.id} clickHandler={this.clickHandler} />
        <div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>
Run Code Online (Sandbox Code Playgroud)

或者是否有一些方法可以像普通DOM一样冒泡事件?

小智 33

React在捕获和冒泡阶段支持其虚拟DOM的合成事件(如下所述:https://facebook.github.io/react/docs/events.html).

这意味着您可以在根目录附近的任何DOM元素上放置onClick处理程序,它应该触发页面上的所有Click事件:

<root>
  <div onClick={this.handleAllClickEvents}>
    <comp1>
      <comp2>
        <target>
          <div id={this.props.id}>click me</div>
Run Code Online (Sandbox Code Playgroud)

但是,由于它将触发所有单击事件,因此您需要在单击处理程序中消除它们之间的歧义(这会产生一些相当丑陋的代码).

function handleAllClickEvents(event) {
  var target = event.relatedTarget;
  var targetId = target.id;
  switch(targetId) {
    case 'myBtn1':
      // handle myBtn1 click event
    case 'myBtn2':
      // handle myBtn2 click event
  }
}
Run Code Online (Sandbox Code Playgroud)

这种风格的事件委派实际上是React所做的事情(https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-代表团)所以你必须问问自己这是不是你真正想做的事情.

或者,您可能希望查看Flux中的Dispatcher模式(https://reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html).这是一个更复杂的开始,但它是一个更好的解决方案整体.


Cla*_*kie 5

您可以使用速记将道具传递给子组件

<Component {...this.props} more="values" />
Run Code Online (Sandbox Code Playgroud)

转移道具

因此,在您的情况下:

<root />
  <comp1 clickHandler={this.action}/>
    <comp2 {...this.props} />
      <target {...this.props} id={this.props.id} />
        <div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>
Run Code Online (Sandbox Code Playgroud)

  • 尽管{... this.props}可以正常工作,但很难对组件中传递的内容进行推理,而在维护具有数百个组件的项目后,就很难跟踪了。 (2认同)
  • 我没有使用过很长时间的反应,所以请带一点盐,但是如果您试图分离组件并重用它们,这对我来说似乎是一种反模式。这种模式使它们依赖于具有特定命名属性的父对象的子代。 (2认同)