Reputation: 419
I am new to React and programming in general and have a question regarding componentWillReceiveProps
method. Inside the LikesComponent
class there is updateLikes
method that does ReactDOM.render(<LikesComponent likes={this.props.likes+1} />, document.getElementById("app"))
. I thought that every time <ComponentName />
is called a new instance is going to be created, that's why I was very surprised when I saw a message logged by componentWillReceiveProps
method. Instead, I was expecting to see messages logged by getDefaultProps, getInitialState and render
methods. So, doesn't calling <ComponentName />
always create a new instance of that class? Could you please elaborate on when a new instance is created and when the instance is just updated? I am quite confused now. Thanks in advance.
body {
padding: 40px;
font-family: "helvetica neue", sans-serif;
}
.container {
width: 600px;
margin: auto;
color: black;
padding: 20px;
text-align: center;
}
.container h1 {
margin: 0;
padding: 20px;
font-size: 36px;
}
.container .btn {
border: 0;
padding: 15px;
margin: 10px;
width: 20%;
font-size: 15px;
outline: none;
border-radius: 3px;
color: #FFF;
font-weight: bold;
}
.btn.blue-btn {
background-color: #55acee;
box-shadow: 0px 5px 0px 0px #3C93D5;
}
.btn.blue-btn:hover {
background-color: #6FC6FF;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
var LikesComponent = React.createClass({
updateLikes: function() {
ReactDOM.render(
<LikesComponent likes={this.props.likes+1}/>,
document.getElementById("app")
)
},
getDefaultProps: function() {
console.log("getDefaultProps");
return({
likes: 0
})
},
getInitialState: function() {
console.log("getInitialState");
return({
popular: false
})
},
componentWillReceiveProps: function(nextProps) {
console.log(nextProps);
console.log("Componentwillreceiveprops");
this.setState({
popular: nextProps.likes >= 10
})
},
render: function() {
console.log("Component Rendered");
return (
<div className="container">
<h1>{this.state.popular ? "I'm popular" : null}</h1>
<button className="btn blue-btn" onClick={this.updateLikes}>Likes: {this.props.likes}</button>
</div>
)
}
});
ReactDOM.render(
<LikesComponent />,
document.getElementById("app")
);
</script>
</body>
</html>
Upvotes: 1
Views: 253
Reputation: 39182
All <LikesComponent likes={5} />
does it create an object that means "we want to render a LikesComponent
instance here with these props (likes=5)".
React will compare this new set of things to render with the set of things it has already rendered and think "hey I am already rendering a LikesComponent
with (likes=4)".
Since the component type is the same and it is in the same place in the hierarchy, React will just update the instance with the new prop values instead of destroying the old instance and creating a new instance.
So basically:
New instances are created (mounted) when a component is rendered in a location in the hierarchy where an instance of that component currently does not exist.
Instances are reused when a component is rendered in a location in the hierarchy where an instance of the component already exists.
Instances are destroyed (unmounted) when, on a new render, a component of that type is not rendered to the location where the instance exists.
Upvotes: 2