简体   繁体   English

反应不通过道具将状态传递给孩子

[英]React not passing state to child via props

I am trying to pass my parent App state to a child component Chart . 我试图将我的父App状态传递给子组件Chart

App 应用

constructor() {
    super();
    this.state = {
        dataPoints: {
            '424353': {
                date: '10/10/2016',
                qty: '95'
            },
            '535332': {
                date: '10/11/2016',
                qty: '98'
            },
            '3453432': {
                date: '10/01/2017',
                qty: '94'
            }
        }
    };
    this.addPoint = this.addPoint.bind(this);
}

addPoint(dataPoint) {
    let dataPoints = {...this.state.dataPoints};
    const timestamp = Date.now();
    dataPoints[timestamp] = dataPoint;
    this.setState({ dataPoints: dataPoints });
    console.log('new state', this.state.dataPoints);
}

render() {
    return (
        <div className="app">
            <Chart dataPoints={this.state.dataPoints} />
            <FormControl addPoint={this.addPoint} />
        </div>
    );
}

Chart 图表

composeData() {
    Object
        .keys(this.props.dataPoints)
        .forEach(key => {
            ** do stuff **
        });

    return **stuff**;
}

componentWillUpdate() {
    this.composeData();
}

The addPoint method works, ie I can see in the React console that the new datapoint is added to the state. addPoint方法有效,即我可以在React控制台中看到将新数据点添加到状态中。 But it is not reflected in the Chart component. 但是它没有反映在Chart组件中。 More oddly (to me) is the fact that when I've added a point, the console.log line in my addPoint method (above): 对我来说,更奇怪的是,当我添加一个点时,我的addPoint方法中的console.log行(上面):

console.log('new state', this.state.dataPoints)

does not show the new data point. 不显示新的数据点。

Because setState is asynchronous , use this you see the updated values: 因为setStateasynchronous ,所以使用它可以看到更新的值:

this.setState({ dataPoints: dataPoints }, () => {
     console.log('new state', this.state.dataPoints);
});

Second thing is, whenever any change happen to props values, componentWillReceiveProps lifecycle method will get called, do the computation in this method once you add the new item. 第二件事是,每当props值发生任何变化时,都会调用componentWillReceiveProps生命周期方法,一旦添加新项,就使用该方法进行计算。 Like this: 像这样:

componentWillReceiveProps(newProps) {
    console.log('update props values', newProps);
    Object
        .keys(newProps.dataPoints)
        .forEach(key => {
            ** do stuff **
        });

    return **stuff**;
}

Check this answer for complete explanation: why setState is asynchronous. 检查此答案以获取完整的解释: 为什么setState是异步的。

In add point 在加点

addPoint(dataPoint) {
    let dataPoints = {...this.state.dataPoints};
    const timestamp = Date.now();
    dataPoints[timestamp] = dataPoint;
    this.setState({ dataPoints: dataPoints });
    console.log('new state', this.state.dataPoints);
}

In the above code you do not see the updated value because setState takes time to mutate, You must log it in the setState call back 在上面的代码中,您看不到更新后的值,因为setState需要花费时间才能进行更改,您必须将其记录在setState回调中

this.setState({ dataPoints: dataPoints }, function(){
    console.log('new state', this.state.dataPoints);
 });

And also in the Chart component you need to bind the composeData function if you are using this.props inside it like 而且在Chart组件中,如果要在内部使用this.props ,则需要绑定composeData函数,例如

composeData = () =>{
    Object
        .keys(this.props.dataPoints)
        .forEach(key => {
            ** do stuff **
        });

    return **stuff**;
}

However componentWillMount is only called once and hence you will want to call the composeData function from componentWillReceiveProps also like 但是componentWillMount仅被调用一次,因此您将需要从componentWillReceiveProps调用composeData函数,例如

componentWillReceiveProps(nextProps) {
     this.composeData(nextProps)
}
componentWillMount() {
      this.composeData(this.props.dataPoints) 
 }
composeData(props){
        Object
            .keys(props.dataPoints)
            .forEach(key => {
                ** do stuff **
            });

        return **stuff**;
    }

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM