背景:
在日常开发中,有时候因为种种 原因,代码会报错,最终导致页面崩溃的结果;这种情况会给 用户非常不好的体验;所以,我们可以做一个报错边界;即封装这么一个报错组件,然后将业务组件被该组件包裹,这样业务组件即使报错,也不过逃出这个边界,即将报错控制在一定范围内,不至于让整个页面给崩溃了;同时在报错的情况下,还能在页面进行一定的提示;一来用户比较好的提示;二来,直接能知道是哪个组件发生了错误,能快速定位到。
封装的报错边界组件:
import React, { ReactNode } from 'react';
export class ErrorBoundary extends React.Component<{ children: React.ReactNode, displayText?: string }, { hasError: boolean }> {
/**
* 构造函数用于ErrorBoundary组件的初始化
* @param props - 传递给组件的属性
* @return 没有返回值
*/
constructor(props: { children: ReactNode; displayText?: string }) {
super(props);
this.state = {
hasError: false,
Error: null,
ErrorInfo: null,
};
}
/**
* 捕获错误并更新状态以指示发生了错误
* @param error - 发生的错误。
* @return 更新后的状态,其中hasError设置为true。
*/
static getDerivedStateFromError(error: any) {
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}
/**
* 在渲染过程中捕获错误并使用错误信息更新状态的生命周期
* @param error - 被捕获的错误。
* @param errorInfo - 关于错误的额外信息。
*/
componentDidCatch(error: any, errorInfo: any) {
//记录错误日志
console.error("ErrorBoundary caught an error:", error, errorInfo);
}
/**
* 根据错误状态渲染组件
* @return 基于错误状态渲染的内容
*/
render() {
// if (this.state.hasError) {
// return <div>{this.props?.displayText || "渲染出错了,检查控制台"}</div>;
// }
// return this.props.children;
const { hasError, Error, ErrorInfo } = this.state;
const { children } = this.props;
// 如果捕获到异常,渲染降级UI
if (hasError) {
return (
<div>
{/* 错误信息 */}
<h1>{`Error:${Error?.message}`}</h1>
{/* 错误栈 */}
<details style={{ whiteSpace: "pre-wrap" }}>{ErrorInfo?.componentStack}</details>
</div>
);
}
return children;
}
}
调用:
<div>
<ErrorBoundary key="ComponentA" displayText='ComponentA渲染出错'>
<ComponentA params={params} />
</ErrorBoundary>
<ErrorBoundary key="ComponentB" displayText='ComponentB出错'>
<ComponentB ref={childRef} {...{ menuId, createName, form}} />
</ErrorBoundary>
</div>