我应该在什么时候使用 React.cloneElement 对阵 this. props. children?

我仍然是一个菜鸟在反应和在互联网上的许多例子,我看到这种变化渲染的子元素,我觉得混乱。通常我会看到这个:

class Users extends React.Component {
render() {
return (
<div>
<h2>Users</h2>
{this.props.children}
</div>
)
}
}

然后我看到了这样一个例子:

<ReactCSSTransitionGroup
component="div"
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
{React.cloneElement(this.props.children, {
key: this.props.location.pathname
})}
</ReactCSSTransitionGroup>

现在我了解了 api,但是 医生并没有明确说明我什么时候应该使用它。

那么,一个人能做什么,另一个人不能做什么呢? 谁能给我举个更好的例子来解释一下这个问题?

111107 次浏览

编辑:

看看 温妮莎的回答,这是一个更好的解释。

原文:

首先,React.cloneElement示例只有在您的子元素是单个 React 元素时才有效。

几乎所有的 {this.props.children}都是你想要的。 克隆在一些更高级的场景中非常有用,在这些场景中,父组件发送一个元素,子组件需要更改该元素上的一些道具,或者添加诸如 ref 之类的东西来访问实际的 DOM 元素。

在上面的例子中,给出子元素的父元素并不知道组件的键要求,因此它创建了给出的元素的一个副本,并根据对象中的一些唯一标识符添加了一个键。关于键的更多信息: https://facebook.github.io/react/docs/multiple-components.html

事实上,React.cloneElement并不严格地与 this.props.children相关联。

当您需要克隆反应元素(PropTypes.element)来添加/覆盖道具时,它非常有用,而不希望父元素了解这些组件内部构件(例如,附加事件处理程序或分配 key/ref属性)。

反应元素也是 永恒不变

CloneElement (element,[ props ] ,[ ... children ])几乎等价于: <element.type {...element.props} {...props}>{children}</element.type>


然而,React 中的 children道具特别用于遏制(又名 作文) ,与使用道具的 React.Children API 和 React.cloneElement组件配对。子组件可以在内部处理更多逻辑(例如,状态转换、事件、 DOM 测量等) ,同时将渲染部分提供给任何使用它的地方,React 路由器 <switch/>或复合组件 <select/>就是一些很好的例子。

最后一件值得一提的事情是,response 元素不仅限于 props.children。

function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}


function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}

它们可以是任何有意义的支持,关键是为组件定义一个良好的契约,这样它的使用者就可以与底层的实现细节解耦,不管它使用的是 React.ChildrenReact.cloneElement,甚至是 React.createContext

props.children不是真正的儿童,而是儿童的 描述符。所以你实际上没有什么需要改变的; 你不能改变任何道具,或者编辑任何功能; 你只能改变 念出来。如果您需要进行任何修改,您必须使用 React.CloneElement创建 新元素

Https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components

举个例子:

App.js这样的组件的主渲染函数:

render() {
return(
<Paragraph>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}

现在让我们假设你需要给 Paragraph的每个孩子加一个 onClick,那么在你的 Paragraph.js中你可以这样做:

render() {
return (
<div>
{React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onClick: this.props.onClick })
})}
</div>
)
}

那么你可以简单地这样做:

render() {
return(
<Paragraph onClick={this.onClick}>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}

注意: React.Children.map函数将只看到 顶层元素,它不会看到这些元素呈现的任何内容; 这意味着您为子元素(这里是 <Sentence />元素)提供了直接支持。如果您需要进一步传递道具,假设您在想要使用 onClick道具的 <Sentence />元素中有一个 <div></div>,那么在这种情况下您可以使用 Context API 来完成。使 Paragraph成为提供者,使 Sentence成为消费者。