将获取的数据作为道具(JSON)进行声明,以便呈现数据

时间:2018-07-21 21:35:48

标签: javascript json reactjs react-lifecycle react-state-management

当前,我在运行传奇时从JSON格式的API获取数据。组件装入后,提取过程开始。这意味着该组件渲染两次。

现在,当数据可用作道具时。我可以使用它来渲染它。

我的处理方法如下,我有一个:

  1. 初始状态的构造函数
  2. 我在“ componentDidMount”中获取数据
  3. 我有个函数,它从props中获取JSON属性并将其放入新变量中
  4. 当道具包含获取的数据时,我在render()函数中运行此函数

此方法中的问题:组件运行数据变为“结构化”的函数后,呈现函数循环,然后过一段时间后,属性值将显示为控制台中显示警告消息。

我的问题

  1. 如何防止render()运行一次时发生循环?
  2. 我该如何设计,以便将获取的对象的特定属性合并到一个新对象中,以及如何

我希望我描述了我的问题中最重要的事情。这是代码:

class Dashboard extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        deviceInfo: {
            name: "Initial Name",
            batLevel: "78%",
        }
    }
}

componentDidMount() {
    this.props.requestApiData();
}

updateDeviceInfoWithState (){
    const devices = (this.props.data.data);

    if(devices){
        const newDeviceInfo = this.state.deviceInfo;
        newDeviceInfo.name = devices[0].shadow.desired.payload.refAppData.name;
        newDeviceInfo.batLevel = devices[0].shadow.reported.payload.refAppData.batteryState.level;
        this.setState({
            deviceInfo: newDeviceInfo,
        });
    }
}

render() {
    this.updateDeviceInfoWithState()

    return (
        <div className='container'>
              <p> {this.state.deviceInfo.name} </p>
              <p> {this.state.deviceInfo.batLevel} </p>
        </div>
    )
}...

2 个答案:

答案 0 :(得分:1)

在render方法中更新状态不是一个好习惯,因为这可能会导致无限循环。

在您的情况下,状态是多余的,因为您仅从props中获取数据,或将其替换为默认值。代替使用状态,请在name方法中返回batLevelupdateDeviceInfoWithState,并在render方法中使用它。

示例(未经测试):

class Dashboard extends React.Component {
  componentDidMount() {
      this.props.requestApiData();
  }

  updateDeviceInfoWithState (){
      const devices = this.props.data.data;

      if(devices){
        const device = devices[0].shadow;

        return {
          name: device.desired.payload.refAppData.name,
          batLevel: device.reported.payload.refAppData.batteryState.level
        };
      }

      return  {
        name: "Initial Name",
        batLevel: "78%",
      };
  }

  render() {
      const { name, batLevel } = this.updateDeviceInfoWithState();

      return (
          <div className='container'>
                <p> {name} </p>
                <p> {batLevel} </p>
          </div>
      );
}...

注释1 :如果要将组件与状态分离,最好将简单属性强制为数据输入。例如,该组件需要namebatLevel作为属性。它不需要知道设备的阵列,阴影,有效载荷等。您可以在传奇中接收数据时准备数据,也可以在mapStateToProps中使用redux selector

注意2::如果您确实需要状态中的数据,则可以使用getDerivedStateFromProps生命周期方法(反应16.3),或在{{3 }}(如果您使用的是旧版本。

答案 1 :(得分:0)

在这种情况下,您可以使用ComponentWillRecieveProps方法

fn

}

此方法仅在更改您的组件属性时才运行。