使用异步componentDidMount()好吗?

componentDidMount()在React Native中用作异步函数一种好习惯还是应该避免呢?

我需要从AsyncStorage安装组件时获取一些信息,但是我知道使之成为可能的唯一方法是使componentDidMount()函数异步。

async componentDidMount() {
    let auth = await this.getAuth();
    if (auth) 
        this.checkAuth(auth);
}

这有什么问题吗,还有其他解决方案吗?

A蛋蛋2020/03/12 10:23:51

实际上,建议在ComponentDidMount中进行异步加载,因为React从传统的生命周期方法(componentWillMount,componentWillReceiveProps,componentWillUpdate)转移到了Async Rendering。

这篇博客文章对解释为什么这样做安全并且在ComponentDidMount中提供异步加载示例非常有帮助:

https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

泡芙阿飞斯丁2020/03/12 10:23:51

我喜欢用这样的东西

componentDidMount(){
   const result = makeResquest()
}
async makeRequest(){
   const res = await fetch(url);
   const data = await res.json();
   return data
}
SamStafan十三2020/03/12 10:23:51

您的代码很好,对我来说也很容易理解。请参阅Dale Jefferson的这篇文章,其中显示了一个异步componentDidMount示例,并且看起来也非常不错。

但是有些人会说,阅读代码的人可能会认为React会使用返回的诺言做某事。

因此,对此代码的解释以及是否是一个好的实践都是非常个人的。

如果您需要其他解决方案,则可以使用promises例如:

componentDidMount() {
    fetch(this.getAuth())
      .then(auth => {
          if (auth) this.checkAuth(auth)
      })
}
西门西里2020/03/12 10:23:51

更新:

(我的构建:React 16,Webpack 4,Babel 7):

使用Babel 7时,您会发现:

使用此模式...

async componentDidMount() {
    try {
        const res = await fetch(config.discover.url);
        const data = await res.json();
        console.log(data);
    } catch(e) {
        console.error(e);
    }
}

您将遇到以下错误...

未捕获的ReferenceError:未定义regeneratorRuntime

在这种情况下,您将需要安装babel-plugin-transform-runtime

https://babeljs.io/docs/en/babel-plugin-transform-runtime.html

如果由于某种原因您不希望安装上述软件包(babel-plugin-transform-runtime),那么您将希望遵循Promise模式...

componentDidMount() {
    fetch(config.discover.url)
    .then(res => res.json())
    .then(data => {
        console.log(data);
    })
    .catch(err => console.error(err));
}
十三老丝2020/03/12 10:23:51

我认为只要您知道自己在做什么就可以。但这可能会造成混淆,因为async componentDidMount()componentWillUnmount运行并且卸载了组件之后仍可以运行

您可能还想在内部启动同步和异步任务componentDidMount如果componentDidMount是异步的,则必须将所有同步代码放在first之前await对于某人来说,在第一个代码之前await同步运行的代码可能并不明显在这种情况下,我可能会保持componentDidMount同步,但是让它调用sync和async方法。

无论选择async componentDidMount()vs同步componentDidMount()调用async方法,都必须确保清除在卸载组件时可能仍在运行的所有侦听器或异步方法。

小哥Eva2020/03/12 10:23:51

当您componentDidMount使用async关键字时,文档会这样说:

您可以立即在componentDidMount()中调用setState()。它会触发额外的渲染,但是会在浏览器更新屏幕之前发生。

如果使用async componentDidMount,则将失去此功能:浏览器更新屏幕后,将进行另一个渲染。但是imo,如果您正在考虑使用异步操作(例如获取数据),则无法避免浏览器将屏幕更新两次。在另一个世界中,无法在浏览器更新屏幕之前暂停componentDidMount