渲染React子组件以及其他属性?

时间:2018-04-16 14:13:10

标签: javascript reactjs parent-child

我试图创建的最终结果是一组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>]}
/>

那么,是否有任何其他方式来呈现一个组件实例,该组件实例保存在一个带有附加属性的变量中?

1 个答案:

答案 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));
}