我有这些方法可以进行一些抓取,完成后,它们会设置状态。但是渲染在状态完成之前被调用并且不会更新。
下面的内容似乎可以独立运行,但需要一分钟才能完成。
//returns an promise with Array
getTopIDs(url) {
return fetch(url).then(blob => blob.json()).then(json => json)
}
// makes a URL fetchs JSON and return promise with single ID
getStory(id) {
let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`
return fetch(url).then(blob => blob.json()).then(json => json)
}
// call above methods, set state when done
componentDidMount() { //
let arr = []
let promise = new Promise((resolve, reject) => {
let data = this.getTopIDs("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty").then((idArr) => {
idArr.forEach((id, index) => {
this.getStory(id).then(res => {
arr.push(res)
})
})
//resolve once all pushed to arr
resolve(arr)
})
})
// set state once array is completed
promise.then(res => {
return this.setState({data: arr})
})
}
然后在下面的渲染中记录“不”、“不”并停止。在返回之外尝试它会记录“否”,"is"。为此搜索其他帖子,我尝试在完成时设置一个 bool 值并使用状态回调,但这些都不起作用(完全披露:我真的不明白 setState 回调选项)
render() {
return (
<div>
{
this.state.data.length
? console.log('yes')
: console.log('no')
}
</div>)
}
只有在完成时,我才需要渲染来处理 this.state.data
。我该怎么做?
添加 fiddle :https://jsfiddle.net/drumgod/e2atysu3/6/
最佳答案
您的方法 this.getStory()
是异步的,但您对数组创建的处理在您的 promise 中是同步的。
您需要使用 async/await
或仅在 idArr.forEach()
确定完成后运行您的 resolve(arr)
(使用 Promise.all(idArr.map(...))
可能更容易做到,其中 ...
从 this 返回结果。 getStory()
).
关于javascript - 渲染中的 react 状态在返回中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53658684/