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

标签 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 block 时,这永远不会被调用/触发。

我在这里错过了什么?

最佳答案

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

作为the reference州,

Error boundaries do not catch errors for: <...> Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)

解决方案是在出错时更改组件状态并在下一次渲染时处理它。 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>
    );
  }

关于javascript - 将 ErrorBoundary 与异步生命周期函数一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50022889/

相关文章:

javascript - JQuery UI 菜单防止子菜单项崩溃?

javascript - 将动态编号传递给加载程序

javascript - react setState 替换错误的值

javascript - 如何在媒体查询语法里面使用ng-deep?

typescript - 为什么 `downlevelIteration` 默认不开启?

javascript - Angular 2+ 创建 2 种不同情况的切换

javascript - Nativescript 上是否有任何等效于 HTML anchor 标记的内容?

javascript - 数组拼接和console.log

javascript - React 中的状态管理

arrays - TypeScript:输入带有值或空的数组/元组