映射状态属性返回空数组

时间:2019-07-26 19:16:41

标签: reactjs

我正在编写一个简单的应用程序,该应用程序从xml文件中获取数据。 fetchData函数可以,并返回一个以我的状态存储的数组。

但是当我尝试映射此数组时,它将返回一个空数组。这样我就可以记录我的数据,但是即使我尝试获取lenght属性,它也会返回0 ...

您可以在这里看到我的代码:

import React, { Component } from 'react';
import { parseString } from 'xml2js';
import data from './data';

class App extends Component {
  state = {
    parks: []
  };

  componentWillMount() {
    let { parks } = this.state;
    for (let key of data) {
      this.fetchData(parks, key.name, key.url);
    }
    this.setState({ parks });
  }

  fetchData = (parks, name, url) => {
    let free = '';
    let park = {};
    fetch(url)
      .then(response => response.text())
      .then(xml => {
        parseString(xml, function(err, result) {
          if (result) {
            free = result.park.Free[0];
            while (free[0] === '0') {
              free = free.slice(1);
            }
          } else {
            free = 'no info avaible';
          }
        });
        park = {
          name: name,
          free: free
        };
        parks.push(park);
      });
  };

  render() {
    const { parks } = this.state;
    console.log(parks);
    const parkList = parks.map(({ name, free }) => <div>{name}</div>);
    console.log(parkList);
    return <div>{parkList}</div>;
  }
}

export default App;

console.log(parks)返回如下数组:

[
  {
    "name": "Antigone",
    "free": "245"
  },
  {
    "name": "Arc de Triomphe",
    "free": "91"
  }
]

console.log(parkList)返回一个空数组

1 个答案:

答案 0 :(得分:0)

问题是fetch正在异步运行,并且fetchData将在实际提取完成之前返回。因此,在填充setState对象之前先调用parks,然后使用空的parks对象调用render函数。另外,console.log不是同步运行的,为此,由于引用了该对象,因此获得了不同的输出。

要解决此问题,您必须等待所有提取操作,然后再调用setState

  componentWillMount() {
    let { parks } = this.state;
    const fetches = []
    for (let key of data) {
      fetches.push(this.fetchData(parks, key.name, key.url));
    }
    Promise.all(fetches)
       .then(()=>this.setState({ parks }));
  }

  fetchData = (parks, name, url) => {
    let free = '';
    let park = {};
    return fetch(url)
      .then(response => response.text())
      .then(xml => {
        parseString(xml, function(err, result) {
          if (result) {
            free = result.park.Free[0];
            while (free[0] === '0') {
              free = free.slice(1);
            }
          } else {
            free = 'no info avaible';
          }
        });
        park = {
          name: name,
          free: free
        };
        parks.push(park);
      });
  };

值得一看的是Java语言中的async/await。有了这个,您可以编写出更具可读性和明显性的代码。