我正在用纯Reactjs构建一个简单的应用程序。我遇到问题的组件是应该通过映射一个以前通过从外部API提取一些数据来填充的数组来呈现许多按钮的组件。该数组填充在类方法中,结果最终复制到另一个数组中,该数组是组件状态的一部分
当我在组件的render方法上console.log数组的内容时,一切看起来都很好。但是,如果我尝试通过其索引打印特定元素,则控制台上会打印“ undefined”。结果,地图功能无法呈现所有所需的按钮。
在设法填充数组的过程中,我设法找到了不同的文档,但是到目前为止,没有一篇文章表明我在做任何根本上错误的事情。至少我看不到。
状态存储一个空数组,以componentWillMount方法开头,并在componentWillMount方法内,调用API来获取数据并按照以下说明更新数组:
this.state = {
resources: []
}
getAPIavaiableResources(api_resource) {
let buttonsArray = []
fetch(api_resource)
.then(response => response.json())
.then(data => {
for (let i in data) {
buttonsArray.push({id: i, name: i, url: data[i]})
}
}).catch(error => console.log(error))
this.setState({resources: buttonsArray})
}
componentWillMount() {
this.getAPIavaiableResources(ROOT_RESOURCE)
}
render() {
const { resources } = this.state;
console.log(resources)
console.log(resources[0])
return (
<div className="buttons-wrapper">
{
resources.map(resource => {
return <Button
key={resource.id}
text={resource.name}
onClick={this.handleClick}
/>
})
}
</div>
)
}
这是通过render方法打印到控制台上的内容。
[]
0: {id: "people", name: "people", url: "https://swapi.co/api/people/"}
1: {id: "planets", name: "planets", url: "https://swapi.co/api/planets/"}
2: {id: "films", name: "films", url: "https://swapi.co/api/films/"}
3: {id: "species", name: "species", url: "https://swapi.co/api/species/"}
4: {id: "vehicles", name: "vehicles", url: "https://swapi.co/api/vehicles/"}
5: {id: "starships", name: "starships", url: "https://swapi.co/api/starships/"}
length: 6
__proto__: Array(0)
有人可以看到我在做什么吗?我要推送一个对象是因为我确实想要一个对象数组,尽管Javascript中的数组也是对象。任何帮助将不胜感激。
答案 0 :(得分:1)
您当前的实现方式是在获取数据之前先设置状态,然后在api调用返回时将状态更改。 React无法分辨您何时进行更改,因此不知道要重新渲染。仅当您调用setState(或当它收到新的道具)时,它才知道要重新渲染。
相反,请等到有了数据,然后再使用填充的数组调用setState。
getAPIavaiableResources(api_resource) {
fetch(api_resource)
.then(response => response.json())
.then(data => {
let buttonsArray = []
for (let i in data) {
buttonsArray.push({id: i, name: i, url: data[i]})
}
this.setState({resources: buttonsArray})
}).catch(error => console.log(error))
}
componentDidMount() {
this.getAPIavaiableResources(ROOT_RESOURCE)
}
上面的示例还更新了代码,以使用componentDidMount而不是componentWillMount。 componentWillMount已弃用,无论如何都不打算用于这种情况。
答案 1 :(得分:0)
当前,您正在设置状态,而无需等待承诺被解决。为此,请在this.setState({resources: buttonsArray})
循环之后将for
移动。
此外,您可以有条件地渲染组件,直到通过执行以下操作从远程资源获得所需的内容为止:
render () {
const { resources } = this.state;
return resources.length
? (
<div>Your content...</div>
)
: null // or some loader
}