小编典典

为什么Async Await与React setState一起使用?

reactjs

我在ReactJS项目中一直在使用babel的async await。我发现可以方便地与React
setState一起使用,我想更好地理解它。考虑以下代码:

handleChange = (e) => {
  this.setState({[e.target.name]: e.target.value})
  console.log('synchronous code')
}

changeAndValidate = async (e) => {
  await this.handleChange(e)
  console.log('asynchronous validation code')
}

componentDidUpdate() {
  console.log('updated component')    
}

我的意图是让异步验证代码在组件更新后运行。而且有效!生成的控制台日志显示:

synchronous code
updated component
asynchronous validation code

验证代码仅在handleChange更新状态并呈现新状态后运行。

通常要在状态更新后运行代码,您必须在this.setState之后使用回调。这意味着,如果要在handleChange之后运行任何内容,则必须为其提供回调参数,然后将其传递给setState。不漂亮。但是在代码示例中,等待状态以某种方式等待await知道该handleChange已完成…但是我认为等待仅与promise一起使用,并等待一个promise解析后再继续。handleChange中没有承诺,也没有解决方案。它如何知道要等待什么?

这似乎意味着setState是异步运行的,而await以某种方式知道它何时完成。也许setState在内部使用诺言?

版本:

反应:“ ^ 15.4.2”

babel-core:“ ^ 6.26.0”

babel-preset-env:“ ^ 1.6.0”,

babel-preset-react:“ ^ 6.24.1”,

babel-preset-stage-0:“ ^ 6.24.1”

babel-plugin-system-import-transformer:“ ^ 3.1.0”,

babel-plugin-transform-decorators-legacy:“ ^ 1.3.4”,

babel-plugin-transform-runtime:“ ^ 6.23.0”


阅读 956

收藏
2020-07-22

共1个答案

小编典典

我尽力简化并补充了戴文的答案,因此您可以更好地了解这里的实际情况:


  1. 将await 放在 this.handleChange的 前面,这将 安排 其余 changeAndValidate 函数的执行,仅在 await 解析 其右侧指定的值(在本例中为 this.handleChange 返回的值)时 运行。
  2. *在 *await 右边的 this.handleChange 执行:

2.1。 setState 运行其更新程序,但由于 setState 不保证立即进行更新,因此有可能将更新安排在以后的时间进行
(无论是立即更新还是在以后的某个时间点,重要的是已计划好了)

2.2。console.log(’synchronous code’)运行…

2.3。 this.handleChange 然后退出,返回 未定义
(返回undefined,因为除非明确指定,否则函数返回undefined)

  1. await 然后接受这个 未定义的, 并且因为它不是一个承诺,所以使用 Promise.resolve(undefined) 将其转换为一个已解决的承诺,并等待它-它不会立即可用,因为在幕后它被传递给异步的 .then 方法:

“传递给promise的回调将在当前JavaScript事件循环运行完成之前永远不会被调用”

3.1。这意味着将 undefined 放置在 事件队列 的后面(这意味着它现在在事件队列的setState更新程序之后…)

  1. 事件循环 最终到达并获取我们的 setState 更新,该更新现在执行…

  2. 事件循环 到达并获取 undefined ,其结果为 undefined (如果需要,我们可以存储此值,因此在await前面通常使用= =来存储已解析的结果)

5.1。 Promise.resolve() 现在完成,这意味着 await 不再受影响,因此该函数的其余部分可以恢复

  1. 您的 验证 码运行
2020-07-22