超级面板
文章目录
最新文章
最近更新
文章分类
标签列表
文章归档

React Error Boundaries(错误边界)

过去,组件内部的 JavaScript 错误经常会破坏 React 的内部状态,并导致它在下一次渲染时发生奇奇怪怪的错误。这些错误通常总是由应用程序代码中的早期错误引起,但在之前版本的 React 没有提供在组件中优雅地处理它们的方法。

针对“部分 UI 的错误不应当导致整个应用的崩溃” 这个理念,React16 引入了一个新的概念 “Error Boundaries( 错误边界)”。Error Boundaries 是一个特殊的 React 组件, 它用来捕获发生在子组件树的 js 错误,并输出这些错误,显示一个回调的 UI,避免一个组件的一个错误导致整个组件树的崩溃。

在学习它之前,我们先要了解一下它的不适用场景:

哪些地方可以使用 Error Boundaries

首先我们要知道,它目前不能捕获这些类型的错误:

  • 事件处理器(Event handlers)
  • 异步代码中的错误,比如 setTimeoutrequestAnimationFrame
  • 服务端渲染(Server side rendering)。
  • 它自身代码抛出的异常。

它可以用来处理的错误:

它可以捕获发生在组件的 render 方法和生命周期方法,以及其子孙组件的 render 方法和生命周期方法所抛出的错误。

使用

它也是一个 React 组件,使用方法与其他组件差别不大,区别在于,它需要定义一个新的生命周期方法 componentDidCatch(error, info) :

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}

// use it
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>

需要注意的是,在 React16 中,如果有组件发生应该被 Error Boundaries 捕获的错误,而未被任何的 Error Boundaries 所捕获,将会导致整个 React 组件树的卸载。React 官方文档是这样说明其理念的:

We debated this decision, but in our experience it is worse to leave corrupted UI in place than to completely remove it. For example, in a product like Messenger leaving the broken UI visible could lead to somebody sending a message to the wrong person. Similarly, it is worse for a payments app to display a wrong amount than to render nothing.

我们讨论了这个决定,根据我们的经验,将发生错误的 UI 留在原地比完全删除它会更糟糕。例如,在像 Messenger 这样的产品中,遗留的发生错误 UI 可能会导致某人向错误的人发送消息。同样,支付 App 显示错误的金额比不提供任何内容的结果更糟糕。

为什么不处理Event Handlers 内的错误

与 render 方法和生命周期方法不同,事件处理程序在组件渲染期间不会执行。因此,即使这类错误发生,React 仍然知道应该在屏幕上显示什么,这类错误不需要 Error Boundaries 来处理,使用 try/ catch 处理即可。

参考