componentWillMount最初不基于props更新状态

时间:2017-11-29 20:37:58

标签: javascript reactjs firebase lifecycle

我有1个组件,它接收来自父组件的prop,prop是一个firebase对象数组。

[{date:"string", value:"number"},{...},{...}...]

这样的东西

我的想法是拥有一个对象数组并使用一个循环来循环它并显示<p></p>标记中某些值的平均值

所以我做了这个

componentDidMount(){
   let sum = 0 , avr;
   for(let i = 0; i < this.props.fuelD.length; i++){
     sum += parseInt(this.props.fuelD[i].value);
   }
   avr = ( sum / this.props.fuelD.length).toFixed(2);

   this.setState({averageFuelConsumption:avr})
}

JSX就是这个

<p>Average: {this.state.averageFuelConsumption}</p>

所以我得到的问题是......

{this.state.averageFuelConsumption}的初始(第一次)安装时,我得到NaN ..但是当我加载其他组件然后加载旧组件时,我得到了计算的平均值。

我知道componentWillReciveProps和其他方法...但我不知道如何使用然后我这个案例...而且我的想法是道具本身将在以后填充,我想动态计算平均值..每次在数据库中写入新对象,然后作为父组件中的prop进行拉取和加载。

4 个答案:

答案 0 :(得分:2)

您可以完全避免使用状态或生命周期方法。只需使用一个计算并返回平均油耗的函数,并在渲染方法中调用它。

    calculateAverageConsumption() {
      if (!this.props.fuelD) return 0;

      let sum = 0 , avr;
      for(let i = 0; i < this.props.fuelD.length; i++){
        sum += parseInt(this.props.fuelD[i].value);
      }
      avr = ( sum / this.props.fuelD.length).toFixed(2);

      return avr;
    }

然后在你的渲染方法中调用它:

<p>Average: {this.calculateAverageConsumption()}</p>

每次收到新道具时,该组件都会重新渲染并调用this.calculateAverageConsumption()

答案 1 :(得分:1)

componentDidMount() {
   this.calculateAverageConsumption();
}

calculateAverageConsumption = () => {
   if (!this.props.fuelD) return 0;

   let sum = 0 , avr;
   for(let i = 0; i < this.props.fuelD.length; i++){
      sum += parseInt(this.props.fuelD[i].value);
   }

   avr = ( sum / this.props.fuelD.length).toFixed(2);

   this.setState({
     averageFuelConsumption: avr
   })
}

render() {
  return (
    <p>Average: {this.state.averageFuelConsumption}</p>
  )
}

答案 2 :(得分:1)

来自React docs

  

在安装的组件之前调用componentWillReceiveProps()   收到新的道具。如果您需要更新状态以响应   prop更改(例如,重置它),您可以比较this.props   和nextProps并使用this.setState()执行状态转换   这种方法。

因此,每当道具改变时重新计算averageFuelConsumption

constructor(props) {
  super(props);

  this.state = { averageFuelConsumption: this.calcAverage(props.fuelD) };
}

componentWillReceiveProps(nextProps) {
  this.setState({ averageFuelConsumption: this.calcAverage(nextProps.fuelD) });
}

calcAverage(array) {
  if (!array) 
    return 0;

  const sum = array.reduce((sum, val) => sum + val, 0);
  return (sum / array.length).toFixed(2);
}

答案 3 :(得分:0)

您的数据可能在第一次装入组件时未加载,您可以在执行计算之前记录数据吗?如果是这种情况,计算render方法中的值是个好主意,因为每次props更改时都会再次调用它。 componentDidMount仅在第一次调用。