结合使用ErrorBoundary和异步生命周期功能 [英] Use ErrorBoundary together with asynchronous lifecycle-functions

查看:111
本文介绍了结合使用ErrorBoundary和异步生命周期功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个React组件,以异步方式将数据加载到 componentDidMount 上.

I want to build a React-component which loads the data asynchronously on componentDidMount.

此函数当前的外观(用 TypeScript 编写):

This is what the function currently looks like (written in 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

The render-function returns the markup wrapped in a ErrorBoundary component, which has componentDidCatch implemented. However, this is never called/triggered when the awaited call is rejected and I end up in the catch-block.

我在这里想念什么?

推荐答案

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

async function is syntactic sugar for a regular function that returns a promise. An error in async function results in rejected promise. Even if rejected promise isn't handled anywhere and results in Uncaught (in promise) error, it is not caught by error boundaries.

参考所述,

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

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

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

A solution is to change component state on error and handle it on next render. render is the place where error can be re-thrown synchronously.

示例:

  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>
    );
  }

这篇关于结合使用ErrorBoundary和异步生命周期功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆