[英]Require children of certain type in React Component
I am creating a custom React Component for a Dropdown menu. 我正在为下拉菜单创建自定义React组件。 The structure I had in mind to use this component was something among the lines of 我想到的使用这个组件的结构是其中的一部分
<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>
The way I wanted to implement this, is by having the Dropdown
component check if there is a DropdownTrigger
component in its children, and if there is, clone the given DropdownTrigger
component using React.cloneElement
and pass an onClick
property, that calls a state update on the Dropdown
component. 我想要实现它的方法是让Dropdown
组件检查其子React.cloneElement
是否有DropdownTrigger
组件,如果存在,则使用React.cloneElement
克隆给定的DropdownTrigger
组件并传递onClick
属性,该属性调用状态更新在Dropdown
组件上。
Small code snippet of Dropdown.js
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()
});
}
Is this a correct approach and if so, what would be the cleanest/nicest possible way to validate the Dropdown
component has a DropdownTrigger
as child. 这是一种正确的方法,如果是这样,那么验证Dropdown
组件的最干净/最好的方法是将DropdownTrigger
作为子级。 As this means a developer always has to include a DropdownTrigger
as child of the Dropdown
component, I would like to have a nice way to tell developer they should pass a <TriggerButton>
component as child of the dropdown. 因为这意味着开发人员总是必须包含DropdownTrigger
作为Dropdown
组件的子代,我想有一个很好的方法告诉开发人员他们应该将<TriggerButton>
组件作为下拉列表的子项传递。
I'm also open for suggestions about changes in the structure. 我也愿意接受有关结构变化的建议。 Thanks! 谢谢!
Use React.cloneElement to pass additional properties to child components. 使用React.cloneElement将其他属性传递给子组件。 In combination with instanceof you can do exactly what you want. 结合instanceof,您可以完全按照自己的意愿行事。
It could be something along the lines... 它可能是一些东西......
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.