我刚刚阅读了有关 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
(可能是。