我正在为下拉菜单创建自定义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
组件,如果有,则克隆给定的DropdownTrigger
组件使用React.cloneElement
并传递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>
组件作为子组件下拉列表。
我也愿意接受有关结构变化的建议。谢谢!
答案 0 :(得分:2)
使用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;