错误边界放置位置
- 高层组件:一般放置在距离顶层较近的位置,但又不能太靠近顶层。例如,在整个应用的布局组件附近。这样可以捕获多层嵌套组件内的错误,同时避免捕获与应用初始化等全局相关的错误(如 ReactDOM.render 相关错误,这些错误不能被错误边界捕获)。
- 业务模块边界:在不同业务模块的入口组件处放置错误边界。如果应用由多个独立的业务模块组成,这样可以隔离各个模块的错误,防止一个模块的错误影响其他模块。
错误处理逻辑
- 使用 React Hooks 的 useEffect:
import React, { useEffect, useState } from'react';
const ErrorBoundary = ({ children }) => {
const [hasError, setHasError] = useState(false);
const [error, setError] = useState(null);
const [errorInfo, setErrorInfo] = useState(null);
useEffect(() => {
try {
// 模拟一个可能出错的操作,这里只是示例
throw new Error('Simulated error');
} catch (e) {
setHasError(true);
setError(e);
setErrorInfo(e.message);
}
}, []);
if (hasError) {
// 记录错误,可发送到日志服务
console.log('Error caught:', error, errorInfo);
// 返回友好的错误提示 UI
return <div>An error occurred: {errorInfo}</div>;
}
return children;
};
export default ErrorBoundary;
- componentDidCatch 替代方案:虽然在 React Hooks 中没有直接的 componentDidCatch,但可以通过类似上述 useEffect 的方式在函数组件中实现。当错误发生时,记录错误信息(如使用 console.log 或者发送到第三方日志服务),然后返回一个备用 UI 给用户,避免应用崩溃。
确保良好用户体验和交互性
- 备用 UI:在错误发生时,错误边界返回一个友好的、有指导性的备用 UI,告知用户发生了错误,并可能提供一些操作建议,如重试按钮等。
- 隔离错误:由于错误边界只捕获其子组件树中的错误,所以不会影响其他未受影响的组件。例如,一个电商应用中,商品列表组件出错,错误边界可以捕获该错误,而购物车等其他组件仍可正常交互。
- 错误恢复:如果可能,提供错误恢复机制。例如,对于由于网络问题导致的数据加载错误,可以提供重试按钮,在重试时重新发起网络请求,恢复应用正常状态。
原理
- 错误捕获范围:错误边界只能捕获其子组件树中的渲染错误、生命周期方法中的错误以及构造函数中的错误。它无法捕获异步代码(如 setTimeout 或 Promise 回调)、事件处理函数以及 React 本身的错误(如 ReactDOM.render 错误)。
- 组件隔离:通过在特定位置放置错误边界,将应用划分为不同的错误隔离区域。这样一个区域内的错误不会向上冒泡导致整个应用崩溃,保证其他区域的正常运行。
- 用户体验保障:提供备用 UI 并允许错误恢复,使得用户在遇到错误时不会看到空白页面或无响应的应用,而是得到明确的提示和恢复应用功能的机会,提升了用户体验和应用的健壮性。