Sean's Blog

An image showing avatar

Hi, I'm Sean

這裡記錄我學習網站開發的筆記
歡迎交流 (ゝ∀・)b

LinkedInGitHub

在 React Class-based Components 中使用 Error Boundary 處理錯誤

本文介紹 React Class-based Components 中 Error Boundary 的使用方式。

錯誤邊界 (Error Boundary)

如果今天在某些情況下我們拋出錯誤,但是沒有處理它,就會造成整個 App 崩潰,那麼我們該怎麼處理錯誤呢?

1componentDidUpdate() {
2  if (this.props.users.length === 0) {
3    throw new Error('No users provided!'); // 拋出錯誤
4  }
5}
6

在 JavaScript 中我們常用的就是 try...catch,但是它僅限在一個元件下使用,如果今天是子元件拋出錯誤,想要在父元件 Handle Error 就沒有辦法。

這時候我們就能使用 Error BoundarycomponentDidCatch 生命週期函式來處理這個情況,每當 ErrorBoundary 裡面的子元件拋出錯誤時就會觸發 componentDidCatch。

我們可以將 ErrorBoundary 作為「保護子元件」的父元件,因此 render() 函式的內容就單純只放子元件的內容,也就是 this.props.children

1import { Component } from 'react';
2
3class ErrorBoundary extends Component {
4  componentDidCatch() {}
5
6  render() {
7    return this.props.children;
8  }
9}
10
11export default ErrorBoundary;
12

像這樣將 ErrorBoundary 元件包覆在想要保護的元件外圍(其實 ErrorBoundary 也可以包覆多個元件,不只一個)。

1<ErrorBoundary>
2  <Users users={this.state.filteredUsers} />
3</ErrorBoundary>
4

現在我們就能在 componentDidCatch 加上一些錯誤處理,確保拋出錯誤時整個 App 不會崩潰,反而可以 Catch 那些錯誤並處理它們。

1import { Component } from 'react';
2
3class ErrorBoundary extends Component {
4  constructor() {
5    super();
6    this.state = { hasError: false };
7  }
8
9  componentDidCatch(error) {
10    console.log(error);
11    this.setState({ hasError: true });
12  }
13
14  render() {
15    if (this.state.hasError) {
16      return <p>Something went wrong!</p>;
17    }
18    return this.props.children;
19  }
20}
21
22export default ErrorBoundary;
23

Summary: Class-based vs Functional Components

Helper Decision Tree:

  • General: Prefer Functional Components
  • If you're building an Error Boundary: Use Class-based Components

回顧

看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…

  • Error Boundary

References