React组件收听孙子事件

时间:2019-07-15 18:35:25

标签: javascript reactjs components

我正在开发一个包含ButtonBarButton组件的组件库。

ButtonBar组件将某些children作为Button,然后将它们呈现为漂亮的布局。

因此,在最基本的情况下,使用代码看起来像这样:

<ButtonBar>
  <Button>First Button</Button>
  <Button>Second Button</Button>
  <Button>Third Button</Button>
</ButtonBar>

ButtonBar的一个功能是跟踪最后点击的Button并为其赋予特殊的样式。

要实现此目的,ButtonBar具有如下代码:

updateToggle(child) {
  // update state based on child...
}
componentDidMount() {
  this.children = React.Children.map(this.children, (child) => {
    return React.cloneElement(child, {
      press: () => {
        child.props.press();
        this.updateToggle(child);
      }
    })
  });
}

此代码试图利用Button的{​​{1}}事件(单击时由press对其本身进行调用),然后调用Button' s ButtonBar函数。

这有点像“扩展”按钮的按下功能。

无论如何,当用户执行以下操作时,此模式就会崩溃:

updateToggle

现在<ButtonBar> <Link to="/"><Button>First Button</Button></Link> <Link to="/foo"><Button>Second Button</Button></Link> <Link to="/bar"><Button>Third Button</Button></Link> </ButtonBar> 的直接子代不是Button类型的,我们没有一种简单的方法来确定自定义事件是否在ButtonBar上发生。

Button是否应与其ButtonBar进行交互?

1 个答案:

答案 0 :(得分:1)

如何将Link添加为Button的属性?

<ButtonBar>
  <Button to='/'>First Button</Button>
  <Button to="/foo">Second Button</Button>
  <Button to="/bar>Third Button</Button>
</ButtonBar>

您可以强制将只有Button作为子元素传递给ButtonBar

{React.Children.map( this.props.children, (child, i) => { 
            if (child.type.name === Button.name)
                    React.cloneElement(child, {
                press: () => {
                  child.props.press();
                  this.updateToggle(child);
                }
              })
        })}