将状态传递给preact组件

时间:2018-03-09 00:31:14

标签: javascript reactjs asynchronous ecmascript-6 preact

我有一个新人做出反应/预备。我有一个简单的应用程序从API获取天气预报,我希望这些数据传递给图表组件(precharts)。我遇到的问题是当这个图表被渲染时,数据还没有被提取,我得到类型错误,因为我已经在尝试处理它。我看到另一个问题,其中顶部答案建议在我的父组件的状态尚未评估时有条件地将null而不是组件分配给变量。

在父组件中,我有以下方法设置要传递的状态(由父的构造函数调用):

parseHourly = (parsed_json) => {
    for (let i = 0; i < 7; i++) {
        var h = parsed_json['hourly_forecast'][i]['FCTTIME']['hour'];
        var t = parsed_json['hourly_forecast'][i]['temp']['metric'];
        var pair = {hour: h, temperature: t};
        this.state.temps.push(pair);
    }
}

这是我创建图表的父级渲染方法:

render() {
    let myChart;
    if(this.state.temps) {
        myChart = <Chart temps={this.state.temps}/>
    } else {
        myChart = null
    }

    return (
        <div class={ style.container }>
            ...
            { myChart }
            ...
        </div>
    );
}

在图表组件中,我尝试直接在this.props.temps方法中访问render(),但最终我的值为undefined。 我究竟做错了什么?非常感谢。

2 个答案:

答案 0 :(得分:2)

您需要使用setState功能,创建以前状态的副本,然后将新项目推入。
请参阅React生命周期文档:https://reactjs.org/docs/react-component.html#setstate

以下代码是如何在您的情况下setState。但是,您必须将此函数放在React可以更新状态的位置:

parseHourly = (parsed_json) = > {
  const bufferTemps = JSON.parse(JSON.stringify(this.state.temps));
  for (let i = 0; i < 7; i++) {
    const h = parsed_json['hourly_forecast'][i]['FCTTIME']['hour'];
    const t = parsed_json['hourly_forecast'][i]['temp']['metric'];
    const pair = {
      hour: h,
      temperature: t
    };
    bufferTemps.push(pair);
  }
  this.setState({
    temps: bufferTemps
  });
}

注意:
const bufferTemps = [...this.state.temps]不会为每个项目创建深层副本,也不应该this.state.temps.push(pair) 要解决此问题,我使用JSON.parse(JSON.stringify(this.state.temps))创建深度克隆。

答案 1 :(得分:0)

您似乎正在初始化this.state.temps = [],但在render()方法中,您正在检查if (this.state.temps)。 ==true),因此检查将始终通过。

试试这个:

class Parent extends Component {
  constructor() {
    super();
    this.state.temps = [];
  }
  // ... etc ...
  render() {
    let myChart
    // if we have any temperatures:
    if (this.state.temps.length>0) {
      myChart = <Chart temps={this.state.temps} />
    }
    return <div class={style.container}>{myChart}</div>
  }
}

class Chart extends Component {
  render() {
    // now we know temps will be an Array of 1 or more items:
    console.log(this.props.temps)
  }
}