React 错误边界处理
使用 Error Boundary 统一捕获 React 组件错误
问题
如何统一监听 React 组件报错?
解答
React 提供了 Error Boundary(错误边界)机制来捕获子组件树中的 JavaScript 错误。
创建错误边界组件
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
// 静态方法:根据错误更新 state
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
// 捕获错误信息和组件栈
componentDidCatch(error, errorInfo) {
// 上报错误到监控服务
console.log('错误信息:', error);
console.log('组件栈:', errorInfo.componentStack);
// 可以发送到错误监控平台
// reportError(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 降级 UI
return this.props.fallback || <h1>页面出错了</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
使用错误边界
import ErrorBoundary from './ErrorBoundary';
function App() {
return (
<ErrorBoundary fallback={<div>出错了,请刷新页面</div>}>
<Header />
<ErrorBoundary fallback={<div>内容加载失败</div>}>
<MainContent />
</ErrorBoundary>
<Footer />
</ErrorBoundary>
);
}
错误边界无法捕获的情况
// 1. 事件处理函数中的错误(需要 try-catch)
function Button() {
const handleClick = () => {
try {
throw new Error('点击错误');
} catch (error) {
console.log(error);
}
};
return <button onClick={handleClick}>点击</button>;
}
// 2. 异步代码(setTimeout、Promise)
useEffect(() => {
setTimeout(() => {
// 这里的错误不会被 ErrorBoundary 捕获
}, 1000);
}, []);
// 3. 服务端渲染
// 4. 错误边界组件自身的错误
配合全局错误监听
// 捕获未处理的 Promise 错误
window.addEventListener('unhandledrejection', (event) => {
console.log('未处理的 Promise 错误:', event.reason);
});
// 捕获全局 JS 错误
window.addEventListener('error', (event) => {
console.log('全局错误:', event.error);
});
React 19+ 的新特性
// React 19 支持在 createRoot 时配置错误处理
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'), {
onCaughtError: (error, errorInfo) => {
// 被 ErrorBoundary 捕获的错误
console.log('捕获的错误:', error);
},
onUncaughtError: (error, errorInfo) => {
// 未被捕获的错误
console.log('未捕获的错误:', error);
}
});
关键点
- Error Boundary 只能用 class 组件实现,需要
getDerivedStateFromError或componentDidCatch getDerivedStateFromError用于渲染降级 UI,componentDidCatch用于记录错误- 无法捕获:事件处理、异步代码、SSR、自身错误
- 可以嵌套使用,实现不同粒度的错误处理
- 配合
window.onerror和unhandledrejection实现完整的错误监控
目录