When should I be using React.cloneElement vs this.props.children?
Solution 1:
props.children
isn't the actual children; It is the descriptor of the children. So you don't have actually anything to change; you can't change any props, or edit any functionality; you can only read from it. If you need to make any modifications you have to create new elements using React.CloneElement
.
https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components
An example:
main render function of a component such as App.js
:
render() {
return(
<Paragraph>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
now let's say you need to add an onClick
to each child of Paragraph
; so in your Paragraph.js
you can do:
render() {
return (
<div>
{React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onClick: this.props.onClick })
})}
</div>
)
}
then simply you can do this:
render() {
return(
<Paragraph onClick={this.onClick}>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
Note: the React.Children.map
function will only see the top level elements, it does not see any of the things that those elements render; meaning that you are providing the direct props to children (here the <Sentence />
elements). If you need the props to be passed down further, let's say you will have a <div></div>
inside one of the <Sentence />
elements that wants to use the onClick
prop then in that case you can use the Context API to do it. Make the Paragraph
the provider and the Sentence
elements as consumer.
Solution 2:
Edit:
Look at Vennesa's answer instead, which is a better explanation.
Original:
First of all, the React.cloneElement
example only works if your child is a single React element.
For almost everything {this.props.children}
is the one you want.
Cloning is useful in some more advanced scenarios, where a parent sends in an element and the child component needs to change some props on that element or add things like ref for accessing the actual DOM element.
In the example above, the parent which gives the child does not know about the key requirement for the component, therefore it creates a copy of the element it is given and adds a key based on some unique identifier in the object. For more info on what key does: https://facebook.github.io/react/docs/multiple-components.html