componentDidCatch与渲染中的try / catch有何不同?

时间:2018-03-23 18:13:47

标签: reactjs

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

这让我想知道这与渲染中的简单try catch有何不同,如下所示:

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

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

3 个答案:

答案 0 :(得分:1)

由于@Boy With Silver Wings在评论中发表,React docs很明显地说明了这一点:

  

try / catch很棒,但它只适用于命令式代码:

     

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

     

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

     

错误边界保留了React的声明性质,   并按照您的预期行事。例如,即使发生错误   在由一个深入的setState引起的componentDidUpdate挂钩中   树,它仍然会正确传播到最接近的错误   边界。

值得注意的是,Error Boundaries会捕获渲染错误。这意味着在例如事件处理不会被抓住。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

仅提供一个示例,假设您有一个在useEffect挂钩内引发错误的组件:

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

假设您在ErrorBoundary中使用它:

<ErrorBoundary>
  <ComponentWithError />
</ErrorBoundary>

这不会像使用componentDidCatch

那样显示回退