【问题标题】:How can I get "this" into scope in a ReactJS ES2015 async function?如何在 ReactJS ES2015 异步函数中将“this”纳入范围?
【发布时间】:2016-12-05 08:17:24
【问题描述】:

下面是一个 ES2015 类中的方法。

它不能是箭头函数,因为它是异步函数。

但由于它不是箭头函数,“this”不在作用域内,所以我无法执行 setstate 之类的操作。

有人可以建议我如何将其纳入范围吗?谢谢!

  async doSubmit(email_address, password) {
    this.setState({isSubmitting: true, error: null})
    try {
      let data = await this.props.app.server.doSignIn(email_address, password)
    } catch (jqXHR) {
      let errorType = (jqXHR.status >= 400 && jqXHR.status < 500) ? 'application' : 'system'
      let errorMessage = (errorType === 'application') ? jqXHR.responseJSON.description : jqXHR.error
      this.setState({error: errorMessage, isSubmitting: false})

    }
    // following a signin event make sure the user image changes
    this.props.app.reloadProfileImages()
    try {
      await this.props.app.initializeClouds()
    } catch (err) {
      xog('err', err)
      this.setState({error: errorMessage, isSubmitting: false})
    }
    this.postSignIn(data)
  }

【问题讨论】:

  • 箭头函数也可以是异步的。 const doSubmit = async (email_address, password) =&gt; { ... }
  • @CodingIntrigue 你能指点我一些明确的参考来确认这一点吗?到目前为止我所了解的一切都说“没有异步箭头函数”。
  • 当然,这里是使用箭头的规范:tc39.github.io/ecmascript-asyncawait/#prod-AsyncArrowFunction
  • 你能把this放到一个局部变量中吗?例如var _this = this;
  • @qxz 在课堂情况下这很困难,因为您需要将其存储在doStuff 的范围之外,但仍然允许它访问

标签: javascript reactjs asynchronous scope ecmascript-6


【解决方案1】:

由于您已经使用async/await ES7 功能,您还可以使用属性初始化语法 自动将this 包含在范围内。它在stage-2 Babel 预设中。

class Example extends React.Component {
    doSubmit = async (email_address, password) => {
        this.setState({isSubmitting: true, error: null})
        try {
          let data = await this.props.app.server.doSignIn(email_address, password)
        } catch (jqXHR) {
          let errorType = (jqXHR.status >= 400 && jqXHR.status < 500) ? 'application' : 'system'
          let errorMessage = (errorType === 'application') ? jqXHR.responseJSON.description : jqXHR.error
          this.setState({error: errorMessage, isSubmitting: false})
        }
        ...
    }

    render() {
      return (
        <button onClick={this.doSubmit("test@email.com", "password")} />
      )
    }
}

【讨论】:

  • 仅供参考 async/await 不是 ES7 (ES2016) 的一部分。它将成为 ES2017 的一部分。
  • 谢谢。我认为是时候将命名改为每年一次了,以避免因一个错误而关闭;)
【解决方案2】:

您有几个选择。首先,箭头函数可以是异步的,你只需要将它附加到类的一个属性上:

constructor() {
    this.doSubmit = async (email_address, password) => {

    };
}

这是在Babel REPL 中工作的示例。

如果您想保持类声明的原样,您可以在构造函数中使用bind 以确保this 引用始终绑定到类实例:

constructor() {
    this.doSubmit = this.doSubmit.bind(this);
}

async doSubmit(email_address, password) {
    ...
}

【讨论】:

  • 上例中是否应该有async关键字?
  • @DukeDougal 哎呀!答案的要点,我省略了它:)已修复。
猜你喜欢
  • 2011-07-07
  • 2023-01-16
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
相关资源
最近更新 更多