将ErrorBoundary与异步生命周期函数一起使用

时间:2018-04-25 12:52:07

标签: javascript reactjs typescript asynchronous

我想构建一个React组件,它在componentDidMount上异步加载数据。

这是函数目前的样子(用TypeScript编写):

async componentDidMount(): Promise<void> {
    try {
        const { props: { teamId }, state: { } } = this;
        const awaitableData = await UrlHelper.getDataAsync("some-fancy-url");

        // ... do something with awaitableData
    } catch(e) {
        console.log("Some error occured");
        throw e;
    }
}

render - 函数返回包含在ErrorBoundary组件中的标记,该组件已实现componentDidCatch。 但是,当等待的呼叫被拒绝并且我最终进入catch - 阻止时,这永远不会被调用/触发。

我在这里缺少什么?

2 个答案:

答案 0 :(得分:6)

async函数是返回promise的常规函数​​的语法糖。 async函数中的错误会导致拒绝承诺。即使被拒绝的承诺未在任何地方处理并导致Uncaught (in promise)错误,也不会被错误边界捕获。

the reference所述,

  

错误边界不会捕获以下错误:&lt; ...&gt;异步代码(例如setTimeout或requestAnimationFrame回调)

解决方案是在出错时更改组件状态并在下次渲染时处理它。 render是可以同步重新抛出错误的地方。

example

  state = { error: null };

  async componentDidMount() {
    try {
      await new Promise(resolve => setTimeout(resolve, 2000));
      throw new Error('Foo error');
    } catch (error) {
      this.setState({ error });
    }
  }

  render() {
    if (this.state.error) {
      throw this.state.error;
    }

    return (
      <p>Foo</p>
    );
  }

答案 1 :(得分:0)

让我们来看看Documentation

基本上它说:

  

错误边界是捕获JavaScript错误的React组件   在子组件树中的任何位置,记录这些错误并显示   后备UI而不是崩溃的组件树。错误   边界在渲染,生命周期方法和内部捕获错误   他们下面的整棵树的构造者。

所以基本上当你试图使用ASYNC / AWAIT并且它失败时它会出现在你的函数的CATCH端:

catch(e) {
    console.log("Some error occured");
    throw e;
}

并且componentDidMount不会抛出错误。实际上,如果删除try catch方法,componentDidMount将处理错误。