当前位置: 首页 > news >正文

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 这个库,它封装了更易用的函数式接口。

相关文章:

  • Three.js 系列专题 7:性能优化与最佳实践
  • TVBOX最新配置接口\直播源接口 收集整理【 2025.4】
  • Token无感刷新
  • 蓝桥杯备赛 Day 21 图论基础
  • 拼多多商品详情接口爬虫实战指南
  • 多线程代码案例(线程池)- 4
  • Rust 之四 运算符、标量、元组、数组、字符串、结构体、枚举
  • springboot Filter实现请求响应全链路拦截!完整日志监控方案​​
  • DeepSeek底层揭秘——《推理时Scaling方法》技术对比浅析
  • AI日报 - 2025年4月9日
  • 信息系统项目管理师-第十三章-项目资源管理
  • 2024 Jiangsu Collegiate Programming Contest H
  • 漫步·简单二进制
  • 基于STM32_HAL库的电动车报警器项目
  • 随机数据下的最短路问题(Dijstra优先队列)
  • golang通过飞书邮件服务API发送邮件功能详解
  • echart实现动态折线图(vue3+ts)
  • react的redux总结
  • telophoto源码查看记录
  • Nextjs15 实战 - React Notes CURD 实现
  • 前四个月人民币贷款增加10.06万亿元,4月末M2余额同比增长8%
  • 明查|印度空军“又有一架战机被巴基斯坦击落,飞行员被俘”?
  • 旭辉控股集团主席林中:债务重组是活下来的前提,自营开发业务收缩至少数核心城市
  • 4月国产新能源,降价潮迈入拐点
  • 中美经贸高层会谈在日内瓦结束,中国代表团将举行发布会
  • 让“五颜六色”面孔讲述上海故事,2025年上海城市推荐官开启选拔