ComponentWillReceiveProps from child does not receive new props when setState () in parent
I have a parent component in React called "App" that renders a child component "Calories" with a HighCharts implementation.
What I expect is the React lifecycle, the parent component creates the child component and then calls the component componentDidMount (). Then I use fetch to get the async data and after that setState the parent of the user. Then it will re-render the child component with user = {this.state.user} and it will be available in the child component. But when I register this.props in the child component WillReceiveProps, the custom object doesn't exist. So this line in the child component logs is "undefined":
componentWillReceiveProps: function(){
const series = this.props.series;
console.log("component Will Receive Props")
console.log(this.props);
}
Here is my complete code:
const App = React.createClass({
//parent component to render all elements and hold state
getInitialState(){
return{
user: {},
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
};
},
componentDidMount: function(){
const fb_id = location.pathname.replace("/users/","");
fetch("https://someurl.com/usersdata/" + fb_id)
.then(rsp => rsp.json())
.then(json => {
if(json.error && json.error.message){
throw new Error(json.error.message);
}
this.setState({user:json}, ()=>{
console.log("state updated");
console.log(this.state);
});
});
},
render: function(){
return (
<div className="container">
<div clasNames="row">
<div className="col-xs-12">
{/*Send this.state.user data from fetch to child component*/}
<Calories series={this.state.series} user={this.state.user}/>
</div>
</div>
<div className="row">
<div className="col-xs-7">
<div className="bottom-left" id="weight-line-chart">
<Weight/>
</div>
</div>
<div className="col-xs-5">
<div className="bottom-right" id="avg-calories-pie-chart">
<AverageCal/>
</div>
</div>
</div>
</div>
);
}
});
//Calories Line chart
const Calories = React.createClass({
componentDidMount: function(){
const series = this.props.series;
console.log("component Did Mount");
console.log(this.props);
$(function () {
const myChart = Highcharts.chart('calories-line-chart', {
chart: {
type: 'line'
},
title: {
text: 'Your Calories Over Time'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: series
});
});
},
componentWillReceiveProps: function(){
const series = this.props.series;
console.log("component Will Receive Props")
console.log(this.props);
$(function () {
const myChart = Highcharts.chart('calories-line-chart', {
chart: {
type: 'line'
},
title: {
text: 'Your Calories Over Time'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: series
});
});
},
render:function(){
return(
<div>
<h3>Calories Intake</h3>
<div className="top" id="calories-line-chart">
</div>
</div>
);
}
});
Can anyone please help me on what I am doing wrong?
source to share
componentWillReceiveProps
called when the values ββof the props
child elements (inside the parent component) are updated, you need to get the new values ββas a parameter in this method lifecycle
, for example:
componentWillReceiveProps: function(newProps){ //here
console.log("component Will Receive Props", newProps); //it will log the new values
...
}
this.props
inside componentWillReceiveProps
will have the previous values ββand it will update after this method lifecycle
. If you run console.log(this.props)
inside render
, you will see updated values.
Why do we need to get new values ββas a parameter?
I think the reason (not sure) this method is called when we do setState
in the parent component, whether it is related to the child component or not, so we need to put some logic before doing any task in child (new props and old props are the same or not) this.props
will have old values ββinside this method because of this .
Contact DOC for more details on componentWillReceiveProps
.
source to share