简体   繁体   English

当父级中的setState()时,子级中的componentWillReceiveProps不会收到新的道具

[英]componentWillReceiveProps in child doesn't receive new props when setState() in parent

I have a parent component in React called "App" that renders a "Calories" child component with a HighCharts implementation. 我在React中有一个名为“App”的父组件,它使用HighCharts实现呈现“Calories”子组件。

What I expect is according to the React lifecycle, parent renders child component and then will call componentDidMount(). 我期望的是根据React生命周期,父渲染子组件然后将调用componentDidMount()。 I then use a fetch to get data async and once done it setState's the parent with a user object. 然后我使用fetch来获取数据异步,一旦完成它就使用了用户对象的setState。 Then it would re-render the child component with user={this.state.user} and it will be available in the child component. 然后它将使用user = {this.state.user}重新呈现子组件,并且它将在子组件中可用。 But when i log this.props in the child's componentWillReceiveProps the user object doesn't exist. 但是当我在子的componentWillReceiveProps中记录this.props时,用户对象不存在。 So this line in child component logs "undefined": 所以子组件中的这一行记录为“未定义”:

componentWillReceiveProps: function(){
    const series = this.props.series;

    console.log("component Will Receive Props")
    console.log(this.props);
}

Here is my full 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>
        );
   }
});

Anybody can help me what I am doing wrong? 任何人都可以帮助我,我做错了什么?

componentWillReceiveProps get called when props values of child (inside parent component) will get updated, you need to receive the new values as a parameter in this lifecycle method, like this: componentWillReceiveProps被调用时props子(父组件内)的值将得到更新,您需要接受新的值作为该参数lifecycle方法,就像这样:

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 get updated after this lifecycle method. this.propscomponentWillReceiveProps将有之前的值,它会在这之后得到更新lifecycle方法。 If you do console.log(this.props) inside render , you will see the updated values. 如果在render执行console.log(this.props) ,您将看到更新的值。

Why we need to receive the new values as parameter? 为什么我们需要接收新值作为参数?

I think reason is (not sure), this method get called whenever we do setState in parent component, irrespective of whether that is related to child component or not, so we need to put some logic before doing any task in child (new props and old props are same or not), because of that this.props will have the old values inside this method. 我认为原因是(不确定),每当我们在父组件中执行setState时都会调用此方法,无论是否与子组件相关,因此我们需要在对子进行任何任务之前设置一些逻辑(新的道具和旧道具是否相同),因为this.props将在此方法中具有旧值。

Check the DOC for more details on componentWillReceiveProps . 有关componentWillReceiveProps更多详细信息,请查看DOC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 父级的setState不会触发子级的componentWillReceiveProps - setState of parent does not fire componentWillReceiveProps of child 当父状态更改时,React子道具不会更新 - React child props doesn't update when parent state change 当父母更新它时,孩子的道具不会更新它是 state - Props in child doesn't update when parent updates it's state 通过父组件的setState更改道具时,子组件中的数据列表选项不会更新 - Datalist options in child component won't update when props are changed through parent component's setState React Component不会收到新的道具 - React Component doesn't receive new props 家长重新提交不会更新子道具 - Parent rerender doesn't update child props 在setState之后,子组件将不会使用新的道具进行更新 - Child component won't update with new props after setState 使用通过props传递的函数时,setState不起作用 - setState doesn't work when function passed through props is used 从接收异步数据的父组件接收道具时的setState - setState when receive props from parent component which fetch async data 在redux中更新了状态,以接收新道具,但是由于未重新渲染组件而未在componentWillReceiveProps中设置状态 - State updated in redux receiving new props but state is not setting in componentWillReceiveProps due to which component doesn't re-render
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM