目錄
- 1. 錯誤邊界(Error Boundaries)
- 使用場景
- 寫法(類組件方式):componentDidCatch
- 2. 事件處理器中的錯誤
- 3. 異步函數中的錯誤(如 fetch、Promise)
- 4. 全局未捕獲錯誤(適用于整個 React 應用)
- 5. 在函數組件中實現錯誤邊界
在 HOW - Vue Error Catch 機制和錯誤攔截工具實現 我們介紹過 Vue Catch Error 機制,今天我們主要介紹 React。
React 的錯誤處理機制,主要是通過 錯誤邊界(Error Boundaries) 來捕獲并處理組件樹中的錯誤,確保不會導致整個應用崩潰。
1. 錯誤邊界(Error Boundaries)
錯誤邊界是一個特殊的 React 組件,它可以捕獲其 子組件樹 中發生的 JavaScript 錯誤,并顯示回退 UI,而不是整個應用崩潰。
使用場景
- 渲染過程中的錯誤
- 生命周期方法中的錯誤
- 構造函數中的錯誤
? 不能捕獲:
- 事件處理器中的錯誤
- 異步代碼(比如 setTimeout、Promise)
- 服務端渲染錯誤
- 錯誤邊界本身拋出的錯誤
寫法(類組件方式):componentDidCatch
class ErrorBoundary extends React.Component {state = { hasError: false }static getDerivedStateFromError(error: Error) {return { hasError: true }}componentDidCatch(error: Error, info: React.ErrorInfo) {console.error("錯誤邊界捕獲:", error, info)// 你也可以上報錯誤日志到服務端}render() {if (this.state.hasError) {return <h2>出錯了,請稍后再試。</h2>}return this.props.children}
}
使用:
<ErrorBoundary><MyComponent />
</ErrorBoundary>
第三方工具推薦:WHAT - React 錯誤邊界處理 - react-error-boundary
2. 事件處理器中的錯誤
React 不會自動捕獲事件處理器的錯誤,需自己 try/catch
:
<button onClick={() => {try {throw new Error('點擊錯誤')} catch (err) {console.error('事件錯誤:', err)}
}}>點擊我
</button>
3. 異步函數中的錯誤(如 fetch、Promise)
也需要手動 try/catch
或使用 .catch()
:
useEffect(() => {const fetchData = async () => {try {await someAsyncFn()} catch (err) {console.error('異步錯誤:', err)}}fetchData()
}, [])
4. 全局未捕獲錯誤(適用于整個 React 應用)
你可以在根組件掛載時添加原生 JS 錯誤監聽:
useEffect(() => {window.onerror = function (msg, url, line, col, error) {console.error('全局 JS 錯誤:', error)}window.addEventListener('unhandledrejection', event => {console.error('未處理的 Promise:', event.reason)})
}, [])
5. 在函數組件中實現錯誤邊界
React 暫不支持函數組件作為錯誤邊界。你仍需使用類組件來包裹你的函數組件。
不過社區有一些 workaround,比如使用 react-error-boundary
這個庫,它封裝了更易用的函數式接口。