代码之家  ›  专栏  ›  技术社区  ›  Aleks

将获取的数据作为props(JSON)发送到state以呈现数据

  •  1
  • Aleks  · 技术社区  · 6 年前

    目前,我在运行saga时从一个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 回复  |  直到 6 年前
        1
  •  1
  •   Ori Drori    6 年前

    更新render方法中的状态不是一个好的实践,因为它可能会导致无限循环。

    在您的情况下,state是多余的,因为您只从props获取数据,或者用默认值替换它。而不是使用状态返回 name batLevel updateDeviceInfoWithState 方法,并在 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 :如果要将组件与状态分离,最好强制使用简单属性作为数据的输入例如,此组件需要 名称 蝙蝠水准仪 是的。它不需要知道设备阵列、阴影、有效载荷等……当你在传奇中收到数据时,你可以准备它,或者使用 redux selector 在里面 mapStateToProps 是的。

    注2: 如果您确实需要您所在州的数据,可以使用 getDerivedStateFromProps 生命周期方法(React 16.3),或更新 componentWillReceiveProps 如果你使用旧版本。

        2
  •  0
  •   Gurpreet Singh    6 年前

    对于这种情况,可以使用componentwillreceiveprops方法,如下所示

    componentWillRecieveProps(nextProps) {
    // Condition as per ur requirement.
    If(this.props.data != nextProps.data) {
        this.updateDeviceInfoWithState(nextProps)
    }
    

    }

    此方法仅在更改了ur组件属性时运行。