Skip to main content

Error Boundary

Error Boundary

Error Boundary,即错误边界,是 React 16 引入的一个新概念,主要为了解决一个组件出错不至于整个应用崩溃的问题。

比如有下面的组件树:

Error Boundary
图-1

如果此时,ChildCom3 组件存在问题,会导致整个应用崩溃,这并不是用户想看到的,而错误边界就是用来解决这个问题的。

错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。

import React, { Component } from 'react'

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

static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}

componentDidCatch(error, errorInfo) {
console.log("error>>>", error)
console.log("errorInfo>>>", errorInfo)
}

render() {
if (this.state.hasError) {
// 降级 UI
return <h1>Something went wrong.</h1>;
}

return this.props.children;
}
}

如上创建了一个错误边界组件,该组件有一个 getDerivedStateFromError 静态方法以及 componentDidCatch 实例方法,这两个方法都会在组件渲染出错时调用,但是略有区别。

getDerivedStateFromError

  • 运行时间点:渲染子组件的过程中,发生错误之后,在更新页面之前(整个应用没有崩溃,直接渲染降级 UI)。
  • 注意:只有子组件发生错误,才会运行该函数。
  • 该函数返回一个对象,React 会将该对象的属性覆盖掉当前组件的 state
  • 参数:错误对象。
  • 该函数通常用于改变状态。

componentDidCatch

  • 运行时间点:渲染子组件的过程中,发生错误,更新页面之后(整个应用已经崩溃了,之后再重新渲染整个应用,当然会排除有问题的那一部分UI,那一部分渲染降级UI),由于其运行时间点比较靠后,因此不太会在该函数中改变状态。
  • 该函数通常用于记录错误消息。

通常使用 static getDerivedStateFromError 渲染备用 UI ,使用 componentDidCatch 打印错误信息或进行错误上报。

捕获错误

实际开发中,通常使用错误边界组件来包裹要忽略渲染错误的子组件:

import ChildCom3 from "./ChildCom3";
import ErrorBoundary from "./ErrorBoundary"

function ChildCom1() {
return (
<ErrorBoundary>
<ChildCom3 />
</ErrorBoundary>
);
}

export default ChildCom1;

错误边界组件主要是用来捕获 UI 渲染时的错误,因此如下场景中错误是无法捕获的:

  • 事件处理。
  • 异步代码。
  • 服务端渲染。
  • 它自身抛出来的错误。

总之,错误边界组件仅能处理渲染子组件期间的同步错误。