我有一个不支持generators
和async await
语法的项目。
我用async await
构建了以下代码,因为我看不到其他方法:
this.setState(async lastState => {
const newImagesAmount = lastState.images.length + 20;
const newImages = await this.getImages(this.props.tag, newImagesAmount);
return {
images: newImages
};
});
为什么?在这种情况下,新状态既由旧状态又由promise
的结果构成。
如何将其转换为非async await
语法?
由于两个当前答案都包含相同的错误,因此 please read @dhilt answer + responses 首先说明了哪些错误。
答案 0 :(得分:1)
如果问题中的代码正确,并且您只想清除异步/等待以支持传统的EXECUTE master.dbo.xp_cmdshell
'bcp "\
select ''adam'', \
''kev'', \
''bill'', \
" queryout "\\network\path\file.txt" -t"|" -c -T '
语法,请执行以下操作:
return promise.then(...)
以下简化也可能有效:
this.setState(lastState => {
const newImagesAmount = lastState.images.length + 20;
return this.getImages(this.props.tag, newImagesAmount)
.then(newImages => ({ 'images': newImages });
});
答案 1 :(得分:1)
首先,不可能在await
内使用setState()
。不是因为项目的限制,而是因为每个内部带有await
的函数都应事先声明为async
。并且应使用await
表示法或链接的.then()
进行调用。因此,传递到.setState
的回调应该为async
并用await
进行调用,但是我们知道React无法以这种方式工作。 React期望普通函数并在没有await
或.then()
的情况下调用它。看起来像func.apply(context, funcArgs)
模块中的react-dom
。此外,也不会检查它是否返回Promise。
让我们回到您的最终目标。据我了解,这是关于确保加载延迟数据后状态仍然保持一致。这是另一个限制。除了sync XHR(这确实是一种不好的做法)之外,无法暂停所有执行,直到数据到来为止。也就是说:无论您做什么,都无法100%保证state
在“请求已发送”和“数据已接收”步骤之间没有发生变异。 await
或功能性setState
均不允许冻结执行。是的,您的代码仍在引用“ prevState”变量,但它可能不再是实际组件的状态!
那么你可以做什么:
P.S。因此从setState
函数内部发出请求会引起混乱,并且不会增加任何其他灵活性。
答案 2 :(得分:0)
我认为您可能想要这样的东西
const newImagesAmount = this.state.images.length + 20;
this.getImages(this.props.tag, newImagesAmount).then(newImages =>
this.setState(prevState => ({
..prevState,
images: newImages
})
);
首先,您请求一个新图像,并且该请求基于当前状态。然后(到达结果时)更新状态。
更新后的版本可以保护异步逻辑在请求完成之前免受多次执行
if (!this.state.pending) {
this.setState(lastState => {
const newImagesAmount = lastState.images.length + 20;
this.getImages(this.props.tag, newImagesAmount).then(newImages =>
this.setState(prevState => ({
...prevState,
pending: false,
images: newImages
})
).catch(() =>
this.setState(prevState => ({
...prevState,
pending: false
})
);
return {
...lastState,
pending: true
}
});
}
答案 3 :(得分:0)
我假设此处的lastState实际上只是更新之前的当前状态。尝试这样的事情:
const imageLength = this.state.images.length + 20
this.getImages(this.props.tag, imageLength)
.then(newImages => {
this.setState({images: newImages})
}