React16 引入了 Error Boundaries 即异常边界概念,以及两个新的生命周期函数,来支持 React 运行时的异常捕获和处理。:

  • componentDidCatch(err, info):此生命周期在后代组件抛出错误后被调用。
  • static getDerivedStateFromError(err):此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state

    React16 用于捕获异常的 Hook:useDebugValue

什么是错误边界

React16 引入了 Error Boundaries(异常边界)的概念是为了避免 React 的组件内的 UI 异常导致整个应用的异常。
Error Boundaries(异常边界)是 React 组件,用于捕获它子组件树种所有组件产生的 js 异常,并渲染指定的兜底 UI 来替代出问题的组件。

它能捕获子组件生命周期函数中的异常,包括构造函数(constructor)和 render 函数

而不能捕获以下异常:

  • Event handlers(事件处理函数)
  • Asynchronous code(异步代码,如 setTimeout、promise 等)
  • Server side rendering(服务端渲染)
  • Errors thrown in the error boundary itself (rather than its children)(异常边界组件本身抛出的异常)
  1. import React from 'react';
  2. class ErrorBoundary extends React.Component {
  3. state = {
  4. hasError: false
  5. }
  6. componentDidCatch(err, info) {
  7. this.setState({ hasError: true })
  8. console.log(err, info);
  9. }
  10. render() {
  11. // 如果 render 阶段出现问题,那么使用一个兜底的 UI
  12. if (this.state.hasError) {
  13. return <div>Something went wrong</div>
  14. }
  15. return this.props.children
  16. }
  17. }
  18. export default ErrorBoundary

使用 ErrorBoundary 组件的方式,将组件嵌套在 ErrorBoundary 组件中

  1. import React from 'react'
  2. import ErrorBoundary from '@/components/ErrorBoundary'
  3. class TodoList extends React.Component {
  4. render() {
  5. return new Error('TodoList is Error')
  6. }
  7. }
  8. class Page extends React.Component {
  9. render() {
  10. return (
  11. <ErrorBoundary>
  12. <TodoList/>
  13. </ErrorBoundary>
  14. )
  15. }
  16. }

参考资料

《从源码看React异常处理》
《React 官方文档》