结合使用ErrorBoundary和异步生命周期功能

Kin*_*sin 2 javascript asynchronous typescript reactjs

我想构建一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所述render-function返回标记包裹在一个ErrorBoundary组件,它已componentDidCatch实现。但是,当等待的呼叫被拒绝并且最终出现在catch-block中时,就永远不会调用/触发该事件。

我在这里想念什么?

Est*_*ask 8

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

作为参考状态,

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

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

一个例子

  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>
    );
  }
Run Code Online (Sandbox Code Playgroud)


Pri*_*dez -4

让我们看一下文档

基本上它说:

错误边界是 React 组件,它可以捕获子组件树中任何位置的 JavaScript 错误,记录这些错误,并显示后备 UI,而不是崩溃的组件树。错误边界会在渲染期间、生命周期方法以及其下方的整个树的构造函数中捕获错误。

所以基本上,当您尝试使用 ASYNC/AWAIT 并且失败时,它将退出函数的 CATCH 端:

catch(e) {
    console.log("Some error occured");
    throw e;
}
Run Code Online (Sandbox Code Playgroud)

并且该错误不会被抛出componentDidMount。实际上,如果删除 try catch 方法,componentDidMount错误就会得到解决。