我们知道在生产环境react错误会导致整个页面崩溃,显示为空白页面。
比如下图的错误,导致了左侧页面直接白屏:
由于某一个组件报错导致整个页面崩溃是很严重的问题,那么我们应该如何去降低代码报错带来的影响呢?
我们希望当页面的某一个组件发生报错时,不要影响到其他组件的显示,比如像下图所示的这种模式 。
通过上图可以看到,某一个组件报错了,但是页面的其他内容还是可以正常显示出来的,并没有受到影响。而实现这种效果就需要使用到异常边界了。
什么是异常边界?
异常边界是React 16
以后推出的新特性,使用异常组件可以捕获子组件js的错误,并可以展示备用UI的class
组件。
异常边界如何实现
下面代码实现了一个简单的异常边界组件,需要注意的是,异常边界组件必须使用class
组件,不能使用函数式组件。
下面咱们举个例子封装一个异常边界组件:
class ErrorWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
};
}
static getDerivedStateFromError(error) {
return {
hasError: true,
};
}
componentDidCatch(error, errorInfo) {
// 一些错误上报的操作
// ......
}
render() {
if (this.state.hasError) {
return (
<Result
status="error"
title="哇哦,出现了错误"
subTitle="请联系管理员"
></Result>
);
}
return this.props.children;
}
}
export default ErrorWrapper;
怎么使用异常组件
只需要将组件作为ErrorWrapper
的子组件来使用就可以了,如下代码:
// 定义一个需要渲染的组件
const Child = () => {
return <div>子组件</div>
}
const Child2 = () => {
return <div>子组件2</div>
}
// 在父页面使用异常边界组件包裹该子组件
const Parent = () => {
return <>
<ErrorWrapper><Child /></ErrorWrapper>
<ErrorWrapper><Child2 /></ErrorWrapper>
</>
}
有哪些限制
虽然异常捕获可以捕获子组件的错误,但是它还是存在一些限制,比如:
- 事件里面的报错
- 捕获不了异步代码(比如
setTimeout
,Promise
)中的异常 - 捕获不了服务端渲染的错误
- 假如异常边界组件ErrorWrapper自身报错了,也不能被捕获
请大家根据自身业务需求选择性使用。