溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在React中處理錯誤邊界組件

發布時間:2021-04-12 15:33:08 來源:億速云 閱讀:250 作者:Leah 欄目:開發技術

這期內容當中小編將會給大家帶來有關怎么在React中處理錯誤邊界組件,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

React中的未捕獲的 JS 錯誤會導致整個應用的崩潰,和整個組件樹的卸載。從 React16 開始就是這樣。但是同時React也引入了一個新的概念——錯誤邊界。

定義,是什么

錯誤邊界仍然是一種組件,可以捕獲(打印或者其他方式)處理該組件的子組件樹任何位置的 JavaScript 錯誤,并根據需要渲染出備用UI.

工作方式類似于try-catch,但是錯誤邊界只用于 React 組件。

只有class組件能夠成為錯誤邊界組件。錯誤邊界僅可以捕獲子組件的錯誤,無法捕獲自身的錯誤。

錯誤邊界會在渲染期間,生命周期和整個組件樹的構造函數中捕獲錯誤。如果沒有錯誤邊界處理,渲染的還是崩潰的子組件樹,這顯然不是我們想要的。

通過一個例子來逐步演示要怎么用錯誤邊界:

export default class ErrorTest extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <BugCounter></BugCounter>
        <span>my name is dan</span>
      </div>
    );
  }
}

// Bug 報錯組件
class BugCounter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0,
    };
  }
  click = () => {
    this.setState(({ counter }) => ({ counter: counter + 1 }));
  };
  render() {
    if (this.state.counter === 5) {
      throw new Error("crashed!");
    }
    return (
      <div>
        <h4 onClick={this.click}>{this.state.counter}</h4>
      </div>
    );
  }
}

上面代碼的渲染結果(忽略樣式):

怎么在React中處理錯誤邊界組件

點擊數字0,會逐步遞增。但是數字等于5的時候,組件會拋出一個Error:

怎么在React中處理錯誤邊界組件

Error會引起整個Demo的崩潰,連外部的<span>my name is dan</span>也顯示不出來了,這時還沒有添加錯誤邊界。

生產模式下,會直接白屏,并在控制臺報錯:

怎么在React中處理錯誤邊界組件

getDerivedStateFromError & componentDidCatch

需要一個錯誤邊界來處理這種崩潰。如何定義一個錯誤邊界?

定義一個組件,并實現static getDerivedStateFromError() 或者componentDidCatch() 生命周期方法(可以都實現或者選擇其一)。這個組件就會變成一個錯誤邊界。

關于這兩個生命周期函數,可以通過鏈接查看,總結如下:

componentDidCatch(error, info)

error是拋出的錯誤對象,而info則包含了組件引發錯誤的棧信息。函數在提交階段被調用。是可以執行副作用的。

static getDerivedStateFromError(error)

在子組件拋出錯誤后調用,會將拋出的錯誤作為參數。需要返回一個值,以更新state。該函數在渲染階段調用,不允許出現副作用。如果在捕獲錯誤后需要執行副作用操作,應該在componentDidCatch中進行。

制作錯誤邊界組件

可以使用組合的方式,在要使用的組件上面添加一個錯誤邊界組件包裹一層。該組件需要這些效果:

  • 捕獲子組件錯誤,組件內部記錄出錯狀態

  • 在出錯狀態下顯示備用UI,在正常狀態下顯示子組件

那么就可以像這樣:

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 <h2>Something went wrong.</h2>;
    }

    return this.props.children; 
  }
}

捕獲到錯誤之后的副作用是自定義的,上傳服務器,或者用state記錄再顯示在頁面上:

componentDidCatch(error, errorInfo) {
  // Catch errors in any components below and re-render with error message
  this.setState({
    error: error,
    errorInfo: errorInfo
  })
}

捕獲處理

加上所有代碼,將有問題的組件用錯誤邊界的組件包裹起來,看看結果:

import { Component } from "react";

export default class ErrorTest extends Component {
  render() {
    return (
      <div>
        <ErrorBoundary>
          <BugCounter></BugCounter>
        </ErrorBoundary>
        <span>my name is dan</span>
      </div>
    );
  }
}

// Bug 報錯組件
class BugCounter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0,
    };
  }
  click = () => {
    this.setState(({ counter }) => ({ counter: counter + 1 }));
  };
  render() {
    if (this.state.counter === 5) {
      throw new Error("crashed!");
    }
    return (
      <div>
        <h4 onClick={this.click}>{this.state.counter}</h4>
      </div>
    );
  }
}

// 錯誤邊界處理組件
class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

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

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

    return this.props.children;
  }
}

拋出異常在開發模式下依然是報錯的,但是在使用yarn build之后,再通過http-server掛起來之后,訪問生產的頁面:

怎么在React中處理錯誤邊界組件

可以看到,雖然因為throw error控制臺出錯,但是my name is dan的顯示并沒有被影響,也就是說,錯誤邊界內部的子組件錯誤沒有影響到外部其他組件和元素。

作用范圍

錯誤邊界用于處理子組件生命周期和渲染函數上的錯誤,對于事件處理器,不會在渲染期間觸發,對于事件處理器拋出的異常應該用try catch。

錯誤邊界無法捕獲這些場景中的錯誤:

  • 事件處理

  • 異步代碼

  • 服務端渲染

  • 錯誤邊界自身拋出的錯誤(非子組件)

上述就是小編為大家分享的怎么在React中處理錯誤邊界組件了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女