组件DidCatch与渲染中的try/catch有何不同



我刚刚阅读了有关 react16 功能componentDidCatch,例如本文建议创建一个错误边界组件:http://www.deadcoderising.com/react-16-taking-control-of-your-errors-using-error-boundaries/。

这让我想知道这与渲染中的简单尝试捕获有何不同,如下所示:

const ErrorBoundary = ({children}) => {
    try {
        return children;
    } catch (ex) {
        return (
            <div>Something went wrong</div>
        );
    }
};

我认为有一些区别,否则 React 团队不会添加生命周期方法,但我不清楚它是什么。

正如 Silver Wings 在评论中发布@Boy的那样,React 文档非常明显地指出了这一点:

尝试/捕获很棒,但它仅适用于命令式代码:

try { showButton(); } catch (error) { // ... }

然而,反应组件是声明性的,并指定应呈现的内容:

错误边界保留了 React 的声明性,并按照您的期望行事。例如,即使发生错误在组件DidUpdate钩子中,由某处深处的setState引起树,它仍然会正确传播到最近的错误边界。

值得注意的是,错误边界捕获渲染错误。这意味着在事件处理等过程中发生的错误不会被捕获。

为了提供一个示例,假设您有一个组件在 useEffect 钩子中抛出错误:

const ComponentWithError = () => {
  React.useEffect(() => {
    throw new Error('ooops')
  }, []);
  return <div>test</div>;
};

假设你在 ErrorBoundary 中使用它:

<ErrorBoundary>
  <ComponentWithError />
</ErrorBoundary>

这不会像使用时那样显示回退componentDidCatch

如果引发错误,你可能想要执行其他清理或应用逻辑,而render方法是一个可怕的地方。通常,除了呈现内容外,不应在 render 方法中执行任何操作。在您的示例中,它可能没有任何区别。随着应用程序复杂性的增加,您很有可能想要做其他事情,例如更新 redux 状态。渲染方法不是这样做的合适位置,但生命周期方法(如componentDidCatch(可能是。

最新更新