在React组件中需要特定类型的子组件

Require children of certain type in React Component

本文关键字:组件 类型 React      更新时间:2023-09-26

我正在为下拉菜单创建一个自定义React组件。我想到的使用这个组件的结构是在

行之间的东西。
<Dropdown>
  <DropdownTrigger> // The button that triggers the dropdown to open or close
    open me
  </DropdownTrigger>
  <DropdownButton> // A button inside the dropdown
    Option 1
  </DropdownButton>
</Dropdown>

我想实现这一点的方式,是通过让Dropdown组件检查其子组件中是否有DropdownTrigger组件,如果有,使用React.cloneElement克隆给定的DropdownTrigger组件并传递onClick属性,该属性调用Dropdown组件上的状态更新。

Dropdown.js的小代码片段

  import DropdownTrigger from './DropdownTrigger';
  _toggleDropdown () {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  _renderTriggerButton () {
    const triggerChild = this.props.children.find(child => child.type === DropdownTrigger);
    return React.cloneElement(triggerChild, {
      ...triggerChild.props,
      onClick: () => this._toggleDropdown()
    });
  }

这是正确的方法吗?如果是,验证Dropdown组件有DropdownTrigger作为子组件的最干净/最好的方法是什么?因为这意味着开发人员总是必须包含DropdownTrigger作为Dropdown组件的子组件,我希望有一个很好的方法告诉开发人员他们应该传递<TriggerButton>组件作为下拉菜单的子组件。

我也愿意听取关于结构变化的建议。谢谢!

使用React。cloneElement将附加属性传递给子组件。结合instanceof,你可以做你想做的事情。


可能是这样的…

import React from 'react';
import DropdownTrigger from './DropdownTrigger';
class DropDown extends React.Component {
  constructor(props) {
    super(props);
  }
  ...
  render() {
    return (
      <div>
        {React.Children.map(this.props.children, child => {
          const additionalProps = {}
          // add additional props if it's the DropdownTrigger
          if (child instanceof DropdownTrigger) {
            additionalProps.toggleDropDown = () => { } ...
          }
          return React.cloneElement(child, additionalProps);
        })}
      </div>
    );
  }
}
export default DropDown;