在 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 Boundary 與 componentDidCatch
生命週期函式來處理這個情況,每當 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