【问题标题】:React not passing state to child via props反应不通过道具将状态传递给孩子
【发布时间】:2017-08-22 17:41:18
【问题描述】:

我正在尝试将我的父级 App 状态传递给子组件 Chart

应用

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>
    );
}

图表

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

    return **stuff**;
}

componentWillUpdate() {
    this.composeData();
}

addPoint 方法有效,即我可以在 React 控制台中看到新数据点已添加到状态中。但它并没有反映在Chart 组件中。 (对我来说)更奇怪的是,当我添加一个点时,addPoint 方法中的 console.log 行(上图):

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

不显示新数据点。

【问题讨论】:

    标签: javascript reactjs components state


    【解决方案1】:

    因为setStateasynchronous,所以使用它可以看到更新的值:

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

    第二件事是,每当props 值发生任何变化时,componentWillReceiveProps 生命周期方法将被调用,一旦添加新项目,请在此方法中进行计算。像这样:

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

    查看此答案以获得完整解释:why setState is asynchronous.

    【讨论】:

      【解决方案2】:

      在添加点

      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);
      }
      

      在上面的代码中你看不到更新的值,因为 setState 需要时间来改变,你必须在 setState 回调中记录它

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

      如果你在里面使用this.props,你还需要在 Chart 组件中绑定 composeData 函数

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

      但是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**;
          }
      

      【讨论】:

        猜你喜欢
        • 2023-03-18
        • 2018-12-25
        • 2018-04-09
        • 1970-01-01
        • 2018-08-25
        • 2017-06-03
        • 1970-01-01
        • 1970-01-01
        • 2019-11-16
        相关资源
        最近更新 更多