小编典典

使用异步 componentDidMount() 好吗?

all

在 React Native 中使用componentDidMount()作为异步函数的好习惯还是我应该避免它?

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

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

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


阅读 82

收藏
2022-07-18

共1个答案

小编典典

让我们首先指出差异并确定它如何导致麻烦。

这是异步和“同步”componentDidMount()生命周期方法的代码:

// This is typescript code
componentDidMount(): void { /* do something */ }

async componentDidMount(): Promise<void> {
    /* do something */
    /* You can use "await" here */
}

通过查看代码,我可以指出以下差异:

  1. 关键字:在打字稿中,这async只是一个代码标记。它做了两件事:
    • 强制返回类型为Promise<void>而不是void. 如果您明确指定返回类型为非承诺(例如:void),打字稿将向您吐出一个错误。
    • 允许您await在方法内使用关键字。
  2. 返回类型从更改voidPromise<void>

    • 这意味着您现在可以这样做:
      async someMethod(): Promise<void> { await componentDidMount(); }
  3. 您现在可以await在方法中使用关键字并暂时暂停其执行。像这样:

    async componentDidMount(): Promise<void> {
    const users = await axios.get<string>("http://localhost:9001/users");
    const questions = await axios.get<string>("http://localhost:9001/questions");
    
    // Sleep for 10 seconds
    await new Promise(resolve => { setTimeout(resolve, 10000); });
    
    // This line of code will be executed after 10+ seconds
    this.setState({users, questions});
    return Promise.resolve();
    

    }

现在,他们怎么可能惹麻烦?

  1. async关键字是绝对无害的。
  2. 我无法想象在任何情况下您都需要调用该componentDidMount()方法,因此返回类型Promise<void>也是无害的。

调用返回类型为Promise<void>不带await关键字的方法与调用返回类型为 的方法没有区别void

  1. componentDidMount()由于延迟执行后没有生命周期方法似乎很安全。但是有一个问题。

假设上述this.setState({users, questions});内容将在 10 秒后执行。在延迟时间的中间,另一个......

this.setState({users: newerUsers, questions: newerQuestions});

… 已成功执行并且 DOM 已更新。结果对用户可见。时钟继续滴答作响,10秒过去了。然后延迟this.setState(...)执行,DOM
将再次更新,那个时候老用户和老问题。用户也可以看到结果。

async => 使用withcomponentDidMount()方法非常安全(我不确定 100%)
。我是它的忠实粉丝,到目前为止,我还没有遇到任何让我头疼的问题。

2022-07-18