我正在编写一个简单的应用程序,该应用程序从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)返回一个空数组
答案 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
。有了这个,您可以编写出更具可读性和明显性的代码。