📒REACT笔记👉👉👉ErrorBoundary

代码错误导致程序崩溃,程序员👩‍💻也会崩溃。尤其在React发布16版本以后,子组件的代码错误会使得整个程序崩溃,组件树全部被卸载。然而我觉得React这种行为也是可以理解的,假设我们正在一个支付的页面,由于代码错误,多一个0少一个0的后果任何一个人都承担不起!所以,就有了ErrorBoundary。使用ErrorBoundary组件包裹的子组件如果报错了,并不会导致整个程序崩溃,错误会被ErrorBoundary组件捕获到,ErrorBoundary渲染备用组件。

ErrorBoundary其实是一个特殊的组件,特殊体现在这个组件拥有static getDerivedStateFromError生命周期函数 或者 componentDidCatch生命周期函数(或者同时拥有这个两个生命周期函数)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能够显示降级后的 UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你同样可以将错误日志上报给服务器
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 你可以自定义降级后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

解释一下这两个生命周期,getDerivedStateFromError是一个静态的方法,这个方法可以返回一个新的state对象来覆盖当前statecomponentDidCatch生命周期我们一般在这里进行一些异步操作,比如将错误上报到服务器。

之后我们就可以使用这个ErrorBoundary来包裹组件了。

1
2
3
4
<ErrorBoundary>
  <Button />
  <SomeComponent />
</ErrorBoundary>

ErrorBoundary可以捕获子组件的任何错误吗?并不是,以下错误ErrorBoundary并不能捕获到:

  • 事件处理
  • 异步代码(例如 setTimeout)
  • 它自身抛出来的错误(并非它的子组件)

似乎就这么多内容了,如果想了解进阶内容,可以看看网易云音乐前端写的项目实践 👉 捕获 React 异常

👋

updatedupdated2020-06-212020-06-21