Skip to content

React 里错误怎么接住? ​

渲染期间、生命周期里和构造函数里的错误,用错误边界接住,避免一整棵树卸掉。事件处理、异步代码和 SSR 里的错误,边界接不住,要自己 try/catch 或在 Promise 上处理。

原理 ​

错误边界是类组件,实现 getDerivedStateFromError 或 componentDidCatch。前者用来渲染备用 UI,后者用来打日志。备用 UI 放在边界里面,边界本身不能在 render 里再抛一次。

jsx
class Boundary extends React.Component {
  state = { error: null }
  static getDerivedStateFromError(error) {
    return { error }
  }
  render() {
    if (this.state.error) return <p>这块暂时不可用</p>
    return this.props.children
  }
}

路由级放一个边界,重的第三方组件再单独包一层。这样一块图表挂了,导航还在。

事件里的异常发生在 React 的渲染调用之外,用事件回调里的 try/catch。请求失败进状态,不要抛进渲染。window 上的 error 和 unhandledrejection 用来兜底上报,不能代替边界去渲染备用界面。

追问 ​

函数组件能当边界吗?

不能只靠 Hook 实现 componentDidCatch 的语义。可以写一个类边界,函数组件放在它里面。有的库用 Hook 风格的 API 包了类边界。

开发环境和生产环境的表现?

开发环境会覆盖一层错误提示,方便看栈。生产环境才是用户看到的备用 UI。两套都要看边界有没有包对位置。

易错点 ​

  • 边界放得太靠上,任何错误都变成整页故障。
  • 在事件里抛错,以为边界会渲染备用 UI。
  • 备用 UI 再次抛错,错误冒到更外层,甚至空白页。

相关 ​