React:通过嵌套组件进行事件冒泡

IT技术 javascript events reactjs
2021-05-09 09:29:56

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

<root />
  <comp1 />
    <comp2 />
      <target id={this.props.id}>
        <div>click me</div>

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

//on root component
this.action = function(id){}

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

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

或者有什么方法可以像普通 DOM 一样冒泡事件?

3个回答

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>

但是,由于它将为所有点击事件触发,您需要在点击处理程序中消除它们之间的歧义(这会产生一些非常难看的代码)。

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

这种事件委托的风格实际上是 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)。开始有点复杂,但总体上是一个更好的解决方案。

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

<Component {...this.props} more="values" />

传送props

所以在你的情况下:

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

如果你想区分最后点击的是哪个元素,你可以使用 Event 对象并在那里找到一些有趣的东西,比如 DOM 元素类型。

<AnElement>
 <button onClick={e => this.eventHandler(e)}>Click me</button>
 <input type="text" onClick={e => this.eventHandler(e)}>Click me</input>

eventHandler = (e) => {
        console.log(e, e.nativeEvent.toElement.nodeName);
...}

您会根据点击的内容获得按钮输入这就是我为我的项目寻找的东西。

此外,您可能会在数组表示中找到一棵 DOM 树 数组表示

希望能帮助到你