[进阶指南] 错误边界 ( Day22 )

component 里 JavaScript 的错误常常会破坏 React 的内部 state,并使它在下次 render 的时候发生 神秘的 错误。这些错误总是被应用程序的程序码里更早发生的错误所导致,但 React 并没有提供在 component 里优雅处理它们的方式,而且也无法从错误中恢复。

JavaScript 发生的错误,会导致 React 在 render 的时候、生命周期函式内、或底下一整个 component tree 里的 Class constructor 发生错误。所以 React 以 错误边界 进行处理,捕抓记录那些错误,然後显示在一个 fallback 的使用介面。

  1. React 15 引入了的 unstable_handleError 函式,React 16 正式引入「错误边界」概念,并改名为 componentDidCatch。
  2. 错误边界处理使用 Class component ,如果使用 Hook 择可用 ErrorBoundary 包裹替代。
  3. Class component 里定义 componentDidCatch() 或 static getDerivedStateFromError() 进行错误边界的处理跟错误的追踪

建立 ErrorBoundary Component

  1. 建立一个 ErrorBoundary 的 Component
  2. 确认 ErrorBoundary 不会有任何的问题
  3. 当一般 Component 使用
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 以至於下一个 render 会显示 fallback UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你也可以把错误记录到一个错误回报系统服务
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 你可以 render 任何客制化的 fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

引用 Component 结构如下

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

测试有错误边界 VS 没错误边界

错误边界的设计防止一个元件发生错误造成整个应用程序坏掉。

没错误边界

Codepen 完整例子

有错误边界

Codepen 完整例子

关於错误边界的其他

错误边界就如同 JavaScript 的 catch {},但它是给 component 使用的。只有 class component 可以成为错误边界。实务上,大部分的时间你只会想要宣告错误边界 component 一次,然後在你的应用程序里重复使用它。

要注意错误边界只会捕捉它底下 component tree 里的 component 的错误。

  • 该把错误边界放在哪里
    任何需要他的地方,route component 或是其他小工具外面。

  • 对於未捕捉到的错误的新行为
    在 React 16,没有被错误边界所捕捉到的错误会 unmount 整个 React component tree。

  • Component Stack Traces
    Create React App 建立专案的话,预设会显示错误。但如果是自己建专案引用 React 可在 bible 上加入 @babel/plugin-transform-react-jsx-source 插件。

  • try/catch
    只作用在命令式程序码(imperative code)

  • Event Handler
    在 event handler 里面发生的 JS 错误,错误边界并不会抓取。但如果因为里面造成的渲染错误,错误边界依然会处理。

handleClick = () => {
    //一样会造成 render 错误
    try {
      this.setState(() => Ghost);
    } catch (error) {
      console.log(error)
    }
    
  }

以上今天

参考资料:
https://zh-hant.reactjs.org/docs/error-boundaries.html


<<:  [DAY21] 非同步的 Boxenn Use Case

>>:  Day21-JDK可视化监控工具:jconsole(一)

验证码小帮手完整测试流程 & 完赛心得

今天终於来到第30天了~就在今天,验证码小帮手将迎来总验收! 使用者加入好友 点击身份认证出现授权页...

Day-16 Excel手把手作图表(一)

今日练习档 ԅ( ¯་། ¯ԅ) 经过昨日的介绍後,相信大家都有更认识Excel的图表了,今天就跟着...

Day 17 (Ps)

1.笔刷填色 (云对话框) (影片Ps7) (1)选云图层Ctrl(载入选取)>选前景色>...

[Day22] Websocket Injection

前言 :Websocket除了能建立一个双向通讯通道外,还能干嘛? :当然是拿来Injection阿...

[NestJS 带你飞!] DAY31 - 实战演练 (下)

角色授权设计 前面有提到这次要设计的系统共有三种角色,并且会使用 Casbin 来做授权机制。 提醒...