HOW - React Error Catch 机制
目录
- 1. 错误边界(Error Boundaries)
- 使用场景
- 写法(类组件方式):componentDidCatch
- 2. 事件处理器中的错误
- 3. 异步函数中的错误(如 fetch、Promise)
- 4. 全局未捕获错误(适用于整个 React 应用)
- 5. 在函数组件中实现错误边界
在 HOW - Vue Error Catch 机制和错误拦截工具实现 我们介绍过 Vue Catch Error 机制,今天我们主要介绍 React。
React 的错误处理机制,主要是通过 错误边界(Error Boundaries) 来捕获并处理组件树中的错误,确保不会导致整个应用崩溃。
1. 错误边界(Error Boundaries)
错误边界是一个特殊的 React 组件,它可以捕获其 子组件树 中发生的 JavaScript 错误,并显示回退 UI,而不是整个应用崩溃。
使用场景
- 渲染过程中的错误
- 生命周期方法中的错误
- 构造函数中的错误
❗ 不能捕获:
- 事件处理器中的错误
- 异步代码(比如 setTimeout、Promise)
- 服务端渲染错误
- 错误边界本身抛出的错误
写法(类组件方式):componentDidCatch
class ErrorBoundary extends React.Component {
state = { hasError: false }
static getDerivedStateFromError(error: Error) {
return { hasError: true }
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
console.error("错误边界捕获:", error, info)
// 你也可以上报错误日志到服务端
}
render() {
if (this.state.hasError) {
return <h2>出错了,请稍后再试。</h2>
}
return this.props.children
}
}
使用:
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
第三方工具推荐:WHAT - React 错误边界处理 - react-error-boundary
2. 事件处理器中的错误
React 不会自动捕获事件处理器的错误,需自己 try/catch
:
<button onClick={() => {
try {
throw new Error('点击错误')
} catch (err) {
console.error('事件错误:', err)
}
}}>
点击我
</button>
3. 异步函数中的错误(如 fetch、Promise)
也需要手动 try/catch
或使用 .catch()
:
useEffect(() => {
const fetchData = async () => {
try {
await someAsyncFn()
} catch (err) {
console.error('异步错误:', err)
}
}
fetchData()
}, [])
4. 全局未捕获错误(适用于整个 React 应用)
你可以在根组件挂载时添加原生 JS 错误监听:
useEffect(() => {
window.onerror = function (msg, url, line, col, error) {
console.error('全局 JS 错误:', error)
}
window.addEventListener('unhandledrejection', event => {
console.error('未处理的 Promise:', event.reason)
})
}, [])
5. 在函数组件中实现错误边界
React 暂不支持函数组件作为错误边界。你仍需使用类组件来包裹你的函数组件。
不过社区有一些 workaround,比如使用 react-error-boundary
这个库,它封装了更易用的函数式接口。