我正在React中开发一个应用程序。它有一个简单的搜索框,在Submit上,我正在调用api1,它返回数据数组。 对于数组中的每个项目,我需要调用api2-应该是异步的。 当前的代码是这样的:
onSubmit() {
api1(textboxvalue).then(data => {
let currentComponent = this
if(data matches condition1) {
currentComponent.state.arrayOfElements1.push(data);
}
if(data matches condition2) {
currentComponent.state.arrayOfElements2.push(data);
}
const arrayOfElements1 = this.state.arrayOfElements1
arrayOfElements1.map(function (element) {
api2(element) -> set this.state.data1loaded
})
const arrayOfElements2 = this.state.arrayOfElements2
arrayOfElements2.map(function (element) {
api2(element) -> set this.state.data2loaded
})
}
要求异步检查渲染中的data1loaded和data2loaded状态。但是使用上述代码,只有在api1的承诺完成后才调用render
有什么想法吗?
答案 0 :(得分:1)
您将结果推送到状态,而不是使用会使用新状态重新渲染组件的 setState 方法。这与Promises的异步性质无关,而与React的工作方式有关(简化:更新状态并将状态和prop传递给导致它们呈现的组件)。
我建议在继续前进之前先刷一下React basics。
答案 1 :(得分:1)
@amirKovacevic是完全正确的。您永远不要直接更改状态:https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly
我不太了解您的代码,但我想您想执行以下操作:
onSubmit() {
api1(textboxvalue).then(data => {
if(/* data matches condition1 */) {
this.setState(prevState => ({
arrayOfElements1: [...prevState.arrayOfElements1, data]
}), () => {
const requests1 = Promise.all(this.state.arrayOfElements1.map(function
(element) {
return api2(element)
})).then(data => this.setState({ data1loaded: true })) // I assume you want to have an indication loading was complete
})
}
})
}
请注意,由于我没有使用async / await,因此我陷入了回调地狱。还要注意,我使用了setState回调:https://reactjs.org/docs/react-component.html#setstate
设置状态是异步的,因此,在使用setState
之后,请勿直接使用它,至少如果要使用新值,则不要这样做。
此外,我的示例仅用于第一个元素数组。
哦,我是SO的新手,如果有什么不符合常规SO注释标准的情况,那么抱歉。 :)