我试图创建的最终结果是一组React组件,UI / UX设计人员可以像标准HTML表标签一样使用嵌套自定义组件:
<Widget>
<WidgetHeader>The Title</WidgetTitle>
<WidgetBody>{this.props.greeting} World!</WidgetBody>
</Widget>
使用React&#34;儿童&#34;引用,父Widget
可以渲染这些子组件,但我遇到的问题是想要在孩子们渲染时设置额外的道具(例如在WidgetHeader
上设置点击处理程序或设置CSS类,或者传递道具,以便子组件知道他们正在构建的上下文并且可以填写值,例如greeting
在示例中)。我可以确定哪个孩子是&#34;标题&#34;孩子:
class Widget extends React.Component {
render() {
let headerChild;
React.Children.forEach(this.props.children, child => {
if (child.type.name == 'WidgetHeader') {
headerChild = child;
}
});
return (
<div className="widget-container">
{headerChild}
</div>
);
}
}
但是使用{headerChild}
语法,我无法向其传递其他属性(例如<{headerChild} className="widget-header" />
无效语法)。
我能弄清楚如何做到这一点的唯一方法就是拥有一个假的&#34;包装&#34; Widget
组件中的DOM节点:
return (
<div className="widget-container">
<div className="widget-header">
{headerChild}
</div>
</div>
);
但是这会使DOM变得混乱,并且不会给孩子任何与其所属的父母有任何联系。我可以让Widget
组件创建WidgetHeader
组件:
return (
<div className="widget-container">
<WidgetHeader className="widget-header" {...this.props}>
{headerChild}
</div>
</div>
);
这为孩子提供了很好的联系,让他们知道与之相关的父母,但这些属性仍然没有减少。然后,这使得UI / UX设计师更加尴尬,因为必须有其他方式来标记哪个子元素是标题(或将其作为属性而不是子元素传递):< / p>
<Widget
header={<span><strong>The</strong> Title</span>}
body={[<p>This is the</p><p>body.</p>]}
/>
那么,是否有任何其他方式来呈现一个组件实例,该组件实例保存在一个带有附加属性的变量中?
答案 0 :(得分:2)
要传递其他道具,您可以使用React.cloneElement。
例如,而不是
if (child.type.name == 'WidgetHeader') {
headerChild = child;
}
你可以写
const additionalProps = { foo: () => console.log('bar'); };
if (child.type.name == 'WidgetHeader') {
headerChild = React.cloneElement(child, additionalProps));
}