使用await setState()是正确的吗?

28

我的函数长这样:

this.setState(prevState => ({
 time : prevState.time + 1
}), function() {
 doSomethingWithNewState(this.state.time)
})

在这种情况下使用await是正确的吗?像这样:

await this.setState(prevState => ({
 time : prevState.time + 1
}));
doSomethingWithNewState(this.state.time);

2
不,使用awaitsetstate函数前面并不是正确的方法。如果您想进行异步操作,请在单独的线程中完成,并使用回调函数更新setstate函数。 - kumar k
https://dev59.com/XlYN5IYBdhLWcg3wuKG5 - anshu purohit
6个回答

34

如前所述,您无法等待this.setState。但是,您可以轻松编写自己的可等待setState函数:

promisedSetState = (newState) => new Promise(resolve => this.setState(newState, resolve));

现在你可以打电话了

await promisedSetState({ someState: true });

1
不知道为什么这个没有更多的赞。这是不被建议的吗?对我来说完美地工作着。 - anondev
1
能否使用hooks来实现这个?如果有人能编辑一下答案就太好了。在hooks中,setState的新版本只需要一个参数。 - josealvarez97
1
@josealvarez97 不需要等待,因为你可以添加一个 useEffect 钩子来响应状态变化,其中状态变量是钩子依赖项。此外,如果您认为必须等待状态更改,那么可能您正在做一些错误的事情。使用钩子的思维范式与类生命周期范式完全不同。 - ADTC
这只适用于类组件。 - undefined

23

不,this.setState 不会返回一个 Promise。

因此在这种情况下你不能使用 await。你需要使用回调函数。


1
根据MDN,await表达式可用于“等待的Promise或任何值。” https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await - J.Ko
2
等待不适用于回调函数。您可以测试它。 - Anas
2
@Anas,await 工作正常,请在此处检查 https://next.plnkr.co/edit/0FqhaCGmtV0xkgAx?open=Hello.js&deferRun=1 - Dhaval Patel

4
正如前面的回答所提到的,setState()不返回Promise,因此您无法像您想的那样使用await。 (尽管您也可以等待同步代码)。
当说setState()是“异步”的时候,意思是setState()效果可能会在稍后发生。
此外,在回调函数中读取this.state将会给您组件在回调被执行的那个特定时刻的状态,但这并不是确切的您期望的,因为所有回调函数都是在一批setState()调用之后被调用的。(请参见此问题)。

根据MDN文档,await表达式可用于“Promise或任何需要等待的值。” https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await - J.Ko
1
没错,这就是我在回答的第一句话中所想表达的 :-) - Dan

2

正如David所说,那个promisedSetState函数非常好用。

需要记住的一件事是,如果你在函数中使用了解构赋值来获取state,请不要直接使用解构后的state,因为它是一个const,不会改变。

myFunction = () => {
const { someState } = this.state;
await promisedSetState({someState: someValue });
console.log(someState) <<<--- will be old value
console.log(this.state.someState) <<<--- will be new value
}

2
绝对不是。您可以像这样将回调传递给 setState
this.setState(prevState => ({
 time : prevState.time + 1
}), 
() => doSomethingWithNewState(this.state.time));

有任何钩子解决方案吗? - famfamfam
@famfamfam 试试使用 useEffect 钩子。https://dev59.com/VlMI5IYBdhLWcg3waq7a - Danial Ahmed

-2

1
因为回调函数很丑陋。 - David Schumann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接