🌙 React 如何进行异常捕获
本文介绍React 最新版(19)中各类错误捕获的完整方案,涵盖从组件级到全局的错误处理:
🌙 一、组件级错误捕获(Error Boundary)
class ErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, info) {
logErrorToService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
return <FallbackUI error={this.state.error} />;
}
return this.props.children;
}
}
// 使用方式
<ErrorBoundary>
<UnstableComponent />
</ErrorBoundary>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
适用场景:组件渲染时同步/异步错误、生命周期方法错误
🌙 二、应用级全局捕获
// 1. 全局事件监听(适用于非React错误)
window.addEventListener('error', (event) => {
event.preventDefault();
sendToMonitoring(event.error);
});
// 2. 未捕获的Promise rejection
window.addEventListener('unhandledrejection', (event) => {
event.preventDefault();
trackPromiseError(event.reason);
});
// 3. React 19新增的根错误捕获
const root = createRoot(container, {
onUncaughtError: (error, componentStack) => {
logCrash(error, { stack: componentStack });
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
适用场景:全局JS错误、未处理的Promise rejection、渲染边界外的错误
🌙 三、数据获取错误处理
// 1. 使用Suspense + Error Boundary
<ErrorBoundary>
<Suspense fallback={<Loader />}>
<AsyncDataComponent />
</Suspense>
</ErrorBoundary>
// 2. 使用React 19的use() Hook
function DataLoader() {
try {
const data = use(fetchData());
return <Display data={data} />;
} catch (error) {
return <ErrorRetry message={error.message} />;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
适用场景:API请求失败、GraphQL错误、数据加载异常
🌙 四、资源加载错误
// 1. 图片/脚本等静态资源
<img
src="image.png"
onError={(e) => {
e.target.src = 'fallback.png';
logResourceError('image', e.target.src);
}}
/>
// 2. 动态import组件
const Component = React.lazy(() => import('./Component')
.catch(error => ({
default: () => <ErrorPage code="MODULE_NOT_FOUND" />
})));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
适用场景:CDN资源加载失败、动态import错误
🌙 五、事件处理器错误
// 1. 使用try/catch
const handleClick = async () => {
try {
await submitForm();
} catch (error) {
showToast(error.message);
captureUserActionError(error);
}
};
// 2. 高阶函数封装
function withErrorHandling(fn) {
return (...args) => {
try {
return fn(...args);
} catch (error) {
logInteractionError(error);
}
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
适用场景:用户交互逻辑错误、事件回调异常
🌙 六、类型错误预防(TypeScript)
// 1. 严格类型校验
interface Props {
userId: string; // 必须提供
data?: DataType; // 可选
}
// 2. 新!非空断言
function User({ user }: { user: UserType! }) {
return <div>{user.name}</div>; // 确保user不为null
}
// 3. React 19增强的useState类型
const [count, setCount] = useState<number>(0); // 必须初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
适用场景:props类型错误、状态类型不匹配
🌙 七、错误监控集成
// 1. 错误上报服务封装
export logError = (error, metadata = {}) => {
Sentry.captureException(error, {
tags: {
react_version: React.version,
...metadata
}
});
};
// 2. 全局错误边界(建议在根组件使用)
<ErrorBoundary
fallback={<GlobalErrorPage />}
onError={logError}
/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
🌙 错误处理策略对比表
错误类型 | 捕获方案 | 恢复策略 |
---|---|---|
组件渲染错误 | Error Boundary | 显示备用UI |
异步代码错误 | try/catch + Error Boundary | 重试机制/降级内容 |
资源加载失败 | onError事件 | 加载备用资源 |
网络请求错误 | 拦截器 + Suspense | 重试/离线缓存 |
类型系统错误 | TypeScript严格模式 | 编译时阻断 |
全局未捕获错误 | window.error事件监听 | 记录日志/通知用户 |
🌙 React 19 新增特性
Root Error Handling
createRoot(container, { onUncaughtError: (error, info) => {} });
1
2
3Error Recovery Hooks
useErrorRecovery(() => retryFunction());
1
建议结合 Sentry/BrowserStack 等工具实现完整的错误监控体系。对于关键业务场景,建议实施多层错误防御策略。