Reputation: 9
if i only write {this.props.children}, the third row can not change every second.i need to write {React.cloneElement(this.props.children)}, why?
It is parent下午1:50:27. It is child下午1:50:27. It is child下午1:28:30.
https://codepen.io/yemos/pen/jQveVx/?editors=0011
class A extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
componentDidMount() {
this.timerID = setInterval(() => this.setState({date: new Date()}), 1000);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
render() {
return (
<div>
<h5>It is parent{this.state.date.toLocaleTimeString()}.</h5>
{React.cloneElement(this.props.children)}
{this.props.children}
</div>
);
}
}
class B extends React.Component {
componentWillMount(){
console.log('componentWillMount');
}
render() {
console.log('render');
return <h5>It is child{new Date().toLocaleTimeString()}.</h5>;
}
}
ReactDOM.render(<A><B/></A>, document.getElementById("root"));
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
)
Upvotes: 0
Views: 2503
Reputation: 281834
Since B
is rendered as a child of A
, a re-render of component A will not trigger render
method of component B
and hence no new updates will be flushed to component B
which in your case is the Date data
. Using React.cloneElement ensures that a new element is created for the children and hence the updated value is re-evaluated.
Upvotes: 0
Reputation: 85575
cloneElement clone and return a new React element.
But react elements are immutable. Once you create an element, you can’t change its children or attributes.
Since, you're just returning new date in component B, it will not be updated. You will need to use state date and do the same as you did in the component A.
While cloning works, it's just because, it returns a new react element. But props.children
will return the same element and only updates when it requires.
{new Date().toLocaleTimeString()}
just returns static date.
Upvotes: 1