如何错误边界(Error Boundaries)?

在React里,如果组件在渲染过程中、生命周期方法里或者子组件的构造函数里抛出了JavaScript错误,整个组件树会从根部开始“溃散”,导致白屏。这体验很糟糕。错误边界就是React提供的一种组件,它像安全网一样,能捕获并处理其子组件树中发生的JavaScript错误,并展示一个降级的UI。

错误边界是什么?一种特殊的类组件

目前,错误边界必须用类组件来实现。它通过定义两个生命周期方法:static getDerivedStateFromErrorcomponentDidCatch 来工作。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, error: null };
  }
  static getDerivedStateFromError(error) {
    // 更新 state,下次渲染时会显示降级 UI
    return { hasError: true, error };
  }
  componentDidCatch(error, errorInfo) {
    // 你可以在这里记录错误,上报给监控服务
    logErrorToService(error, errorInfo.componentStack);
  }
  render() {
    if (this.state.hasError) {
      // 你可以渲染任何自定义的降级 UI
      return <h1>哎呀,出错了。请稍后重试。</h1>;
    }
    // 正常情况下,渲染子组件
    return this.props.children;
  }
}

getDerivedStateFromError 用来在错误发生后更新组件的state,触发渲染降级UI。componentDidCatch 则像是一个“副作用”钩子,主要用来记录错误详情,方便你排查问题。

怎么用?包裹可能出错的组件

你把错误边界组件放在可能出错的子组件树的周围。一旦子树里的任何地方抛出错误,错误边界就会拦截它。

<ErrorBoundary>
  <MyBuggyComponent />
</ErrorBoundary>

这样,即使 MyBuggyComponent 崩溃了,也只会影响这个错误边界内部,应用的其他部分仍然能正常工作。

它不能捕获哪些错误?

错误边界不是万能的。它只捕获其子组件树中的以下错误:

  • 渲染期间的错误
  • 生命周期方法中的错误
  • 构造函数中的错误

无法捕获以下错误:

  • 事件处理器里的错误(你得自己用 try/catch
  • 异步代码里的错误(比如 setTimeoutPromise 回调)
  • 服务端渲染的错误
  • 错误边界组件自身抛出的错误(它只能捕获子组件的)

在实践中,你可以在应用顶层放一个错误边界,防止整个应用崩溃。在关键的路由组件或者独立的功能模块外也包裹一层,实现更精细的错误隔离。记住,它只是一个兜底的呈现方案,核心还是要写出健壮的代码,并配合完善的错误上报。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

    暂无评论内容