錯誤處理
JavaScript 是一種彈性的直譯語言,這表示在執行時遇到錯誤是可能的(甚至很容易)。無論是意外情況的結果,還是我們編寫的程式碼中的錯誤,能夠監控錯誤並實作某種形式的復原或優雅的錯誤處理都很重要。
在 Preact 中,我們這樣做的方法是擷取錯誤並將它們儲存為狀態。這讓元件可以攔截意外或中斷的渲染,並切換為渲染其他內容作為後備。
將錯誤轉換為狀態
有兩個 API 可用於擷取錯誤並將它們轉換為狀態:componentDidCatch
和 getDerivedStateFromError
。它們在功能上類似,而且都是可以在類別元件上實作的方法
componentDidCatch 傳遞一個 Error
參數,並可以決定如何根據個別情況對該 Error 做出回應。它可以呼叫 this.setState()
來渲染後備或替代樹狀結構,這將「擷取」錯誤並將其標記為已處理。或者,該方法可以簡單地將錯誤記錄在某個地方,並允許它繼續未處理(崩潰)。
getDerivedStateFromError 是一個靜態方法,它傳遞一個 Error
,並傳回一個狀態更新物件,該物件會透過 setState()
套用到元件。由於此方法總是會產生狀態變更,導致其元件重新渲染,因此它總是將錯誤標記為已處理。
下列範例顯示如何使用任一種方法來擷取錯誤並顯示優雅的錯誤訊息,而不是崩潰
import { Component } from 'preact'
class ErrorBoundary extends Component {
state = { error: null }
static getDerivedStateFromError(error) {
return { error: error.message }
}
componentDidCatch(error) {
console.error(error)
this.setState({ error: error.message })
}
render() {
if (this.state.error) {
return <p>Oh no! We ran into an error: {this.state.error}</p>
}
return this.props.children
}
}
上面的元件是一個相當常見的範例,說明如何在 Preact 應用程式中實作錯誤處理,通常稱為錯誤邊界。
巢狀結構和錯誤冒泡
在 Preact 渲染虛擬 DOM 樹狀結構時遇到的錯誤會「冒泡」,很像 DOM 事件。從遇到錯誤的元件開始,樹狀結構中的每個父元件都有機會處理錯誤。
因此,如果使用 componentDidCatch
實作,錯誤邊界可以巢狀。當元件的 componentDidCatch()
方法不呼叫 setState()
時,錯誤將持續在虛擬 DOM 樹中冒泡,直到它到達具有 呼叫 setState()
的 componentDidCatch
方法的元件。
試試看!
為了測試我們的錯誤處理知識,讓我們為一個簡單的 App 元件新增錯誤處理。App 內部的一個元件可以在某些情況下擲回錯誤,我們想要捕捉這個錯誤,以便我們可以顯示友善的訊息,告訴使用者我們遇到意外的錯誤。