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?

+3


source to share


1 answer


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

.

+2


source







All Articles