反应:在嵌套组件上冒泡点击事件

React: Bubbling up click events on nested components

本文关键字:事件 嵌套 组件 反应      更新时间:2024-04-04

我正在创建一个反应文件树,我将树设置为React组件。树可以采用一个contents属性,该属性是字符串或其他<Tree />组件的数组(这将启用嵌套文件结构 UI(。这些树组件可以无限嵌套。

我需要在嵌套树组件的子级上注册一个单击事件,但我无法让它在第一级嵌套之外工作。我正在处理的简化示例:

//In App - the top level component
 const App = React.createClass({
   _handleChildClick () {
     console.log("this is where all child clicks should be handled");
   },
   render () {
     return (
       <Tree
         handleChildClick={this._handleChildClick}
         contents={[
           <Tree />
         ]}
       />
     );
   }
 });
 //And in the tree component
 <div onClick={this.props.handleChildClick}></div>

如果你想看到更多细节 - 这里是github存储库。

我尝试研究这个问题,看到人们使用{...this.props}但我不确定这是否适用于我的场景 - 如果是这样,我无法让它工作。

感谢您对此的任何帮助。

点击处理在第一级之外不起作用的原因是因为你的第二级树组件(内容数组内的组件(没有获得适当的 prop handleChildClick传入。(顺便说一句,我认为惯例是调用 prop onChildClick,而处理程序函数被称为handleChildClick - 但我跑题了。

我是否正确理解您实际上想通知从单击的组件到顶部的每一层?为此,您需要扩展内容数组内的树组件的 props - 它需要接收其父组件的点击处理程序。当然,你不能静态地写下来,所以需要动态地完成:

在实际呈现其子组件之前,Tree 组件应使用组件的单击处理程序扩展每个子组件,这可以使用函数React.cloneElement来完成(请参阅 API 文档和更详细的讨论(。直接将其应用于组件会让事情变得有点混乱,因为您要在 prop 中传递组件的子组件,因此您需要弄清楚要修改哪个 prop。在这里,稍微不同的布局会对您有很大帮助:

   <Tree handleChildClick={this._handleChildClick}>
       <Tree />
   </Tree>

恕我直言,看起来更好,并使结构更加清晰。您可以通过this.props.children访问内部组件,cloneElement的使用将简单得多。

因此,在树组件中,您可以拥有如下所示的渲染方法:

render () {
  const newChildren = this.props.children.map(child =>
    React.cloneElement(child, {onChildClick: this._handleChildClick}));
  return (
    <div>{newChildren}</div>
  );
}

请注意,如果您混合使用字符串和Tree组件,则此代码将不起作用,因此我的第三个也是最后一个建议是将这些字符串包装成一个非常薄的组件,以便于处理。或者,您当然可以在地图内进行类型比较。