【问题标题】:Async/await in event handler in react反应中的事件处理程序中的异步/等待
【发布时间】:2019-06-22 22:58:43
【问题描述】:

如何在 react 的事件处理程序中使用 async/await?

我了解以下代码有误,因为我正在访问 this.state 以获取客户代码。

<button onClick={handleClick}>Get Customer</button>
async handleClick() {
    let customerCode = this.state.customerCode;
    let customer = await this.service.getCustomer(customerCode);
    this.setState({ customer });
}

也许应该是这样的,但我认为这行不通:

handleClick() {
    this.setState(async (prevState) => {
        let customerCode = prevState.customerCode;
        let customer = await this.service.getCustomer(customerCode);
        return { ...prevState, customer };
    }); 
}

【问题讨论】:

  • 这两种方法对我来说很有意义并且效果很好,你有什么错误吗? this.service.getCustomer(customerCode) 是否返回 Promise?
  • 第一个sn-p有什么问题?
  • Janathas,我认为 react 不支持 setState() 中的异步回调函数。

标签: javascript reactjs async-await


【解决方案1】:

我理解以下代码是错误的,因为我正在访问 this.state 以获取客户代码

是什么让你认为这是错误的?这对我来说似乎是合法的。
如果你在这样的状态(突变)中更新一个值,那么它可能会被认为是反模式,但是以这种方式读取值是非常好的。

话虽如此,我更喜欢破坏 state 或函数体顶部的任何其他对象的属性:

async handleClick() {
  const { customerCode } = this.state;
  let customer = await this.service.getCustomer(customerCode);
  this.setState({ customer });
}

我认为它更具可读性,但两种方式都可以正常工作。

编辑

澄清一下,当我写这两种方式时都可以正常工作,我的意思是有和没有解构。例如 OP 第一个示例和我的示例。

至于这条评论:

this.state 可能已过时

在你的情况下没关系。 setState 唯一需要更新器参数的情况是下一个状态依赖于前一个状态,这里不是这种情况。

【讨论】:

  • 响应对 this.state 的排队更改,因此 this.state 可能是陈旧的。
  • @rm5432 这里的更新不需要是原子的,它只需要按照它被调用的顺序发生,所以即使this.state 恰好在那里是陈旧的,实际上也没有问题。如果setState() 恰好覆盖了customerCode那么这将是有问题的。
【解决方案2】:

如果customerCode 在您查询时发生变化,那会让您陷入混乱。您可以在进行状态更新之前重新检查customerCode

async handleClick() {
    const { customerCode } = this.state;
    const customer = await this.service.getCustomer(customerCode);

    if(customerCode !== this.state.customerCode)
       return;

    this.setState({ customer });
}

【讨论】:

  • 中间的路由转换也是如此。你会得到一个setState 到一个未安装的组件。所以这个模式通常结合isMounted的标志,并在调用setState之前检查它
  • customerCode 在我等待服务器调用时无法更改,因为 UI 的那部分被动画阻止了。然而,这还不够,因为 react 控制状态并且不提供访问状态的可靠方法。所以,我不能确定我正在使用当前的 customerCode 进行服务器调用,这就是引入混乱的条件。
  • @rm5432 不,那么这根本不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 2016-12-22
相关资源
最近更新 更多