React?錯(cuò)誤邊界Error?Boundary使用示例解析
我們?yōu)槭裁葱枰e(cuò)誤邊界
在React組件中可能會(huì)由于某些JavaScript錯(cuò)誤,導(dǎo)致一些無法追蹤的錯(cuò)誤,導(dǎo)致應(yīng)用崩潰。部分 UI 的 JavaScript 錯(cuò)誤不應(yīng)該導(dǎo)致整個(gè)應(yīng)用崩潰。為此,React引入了錯(cuò)誤邊界(Error Boundary)的概念:可以捕獲發(fā)生在其子組件樹任何位置的 JavaScript 錯(cuò)誤,并打印這些錯(cuò)誤,同時(shí)展示降級(jí) UI,而并不會(huì)渲染那些發(fā)生崩潰的子組件樹。
而在React16以后,未捕獲的錯(cuò)誤會(huì)導(dǎo)致React組件樹的卸載,也就是白屏。所以某些情況下還是非常需要使用Error Boundary組件來避免這種比較嚴(yán)重的問題。
如何使用錯(cuò)誤邊界組件
按照React官方的約定,一個(gè)類組件定義了static getDerivedStateFromError() 或componentDidCatch() 這兩個(gè)生命周期函數(shù)中的任意一個(gè)(或兩個(gè)),即可被稱作ErrorBoundary組件,實(shí)現(xiàn)錯(cuò)誤邊界的功能。
其中,getDerivedStateFromError方法被約定為渲染備用UI,componentDidCatch方法被約定為捕獲打印錯(cuò)誤信息。
具體的實(shí)現(xiàn)如下:
//ErrorBoundary.tsx import * as React from 'react'; interface PropsType { children: React.ReactNode; } interface StateType { hasError: boolean, Error?: null | Error, ErrorInfo?: null | React.ErrorInfo, } export class ErrorBoundary extends React.Component<PropsType, StateType> { constructor(props: PropsType) { super(props); this.state = { hasError: false, Error: null, ErrorInfo: null }; } //控制渲染降級(jí)UI static getDerivedStateFromError(error: Error): StateType { return {hasError: true}; } //捕獲拋出異常 componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { //傳遞異常信息 this.setState((preState) => ({hasError: preState.hasError, Error: error, ErrorInfo: errorInfo}) ); //可以將異常信息拋出給日志系統(tǒng)等等 //do something.... } render() { //如果捕獲到異常,渲染降級(jí)UI if (this.state.hasError) { return <div> <h1>{`Error:${this.state.Error?.message}`}</h1> <details style={{whiteSpace: 'pre-wrap'}}> {this.state.ErrorInfo?.componentStack} </details> </div>; } return this.props.children; } }
實(shí)現(xiàn)ErrorBoundary組件后,我們只需要將其當(dāng)作常規(guī)組件使用,將其需要捕獲的組件放入其中即可。
使用方式如下:
//main.tsx import ReactDOM from 'react-dom/client'; import {ErrorBoundary} from './ErrorBoundary.jsx'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( <ErrorBoundary> <App/> </ErrorBoundary> );
//app.tsx import * as React from 'react'; function App() { const [count, setCount] = useState(0); if (count>0){ throw new Error('count>0!'); } return ( <div> <button onClick={() => setCount((count) => count + 1)}> count is {count} </button> </div> ); } export default App;
點(diǎn)擊按鈕后即可展示拋出異常時(shí),應(yīng)該渲染的降級(jí)UI:
使用錯(cuò)誤邊界需要注意什么
沒有什么技術(shù)棧或者技術(shù)思維是銀彈,錯(cuò)誤邊界看起來用得很爽,但是需要注意以下幾點(diǎn):
- 錯(cuò)誤邊界實(shí)際上是用來捕獲render階段時(shí)拋出的異常,而React事件處理器中的錯(cuò)誤并不會(huì)渲染過程中被觸發(fā),所以錯(cuò)誤邊界捕獲不到事件處理器中的錯(cuò)誤。
- React官方推薦使用try/catch來自行處理事件處理器中的異常。
- 錯(cuò)誤邊界無法捕獲異步代碼中的錯(cuò)誤(例如
setTimeout
或requestAnimationFrame
回調(diào)函數(shù)),這兩個(gè)函數(shù)中的代碼通常不在當(dāng)前任務(wù)隊(duì)列內(nèi)執(zhí)行。 - 目前錯(cuò)誤邊界只能在類組件中實(shí)現(xiàn),也只能捕獲其子組件樹的錯(cuò)誤信息。錯(cuò)誤邊界無法捕獲自身的錯(cuò)誤,如果一個(gè)錯(cuò)誤邊界無法渲染錯(cuò)誤信息,則錯(cuò)誤會(huì)冒泡至最近的上層錯(cuò)誤邊界,類似于JavaScript中的cantch的工作機(jī)制。
- 錯(cuò)誤邊界無法在服務(wù)端渲染中生效,因?yàn)楦镜匿秩痉椒ㄒ呀?jīng)
ReactDOM.createRoot().render()
修改為了ReactDOM.hydrateRoot()
, 而上面也提到了,錯(cuò)誤邊界捕獲的是render階段時(shí)拋出的異常。
以上就是React 錯(cuò)誤邊界Error Boundary使用示例解析的詳細(xì)內(nèi)容,更多關(guān)于React 錯(cuò)誤邊界的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React生命周期方法之componentDidMount的使用
這篇文章主要介紹了React生命周期方法之componentDidMount的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的散點(diǎn)圖 (V3版本)
散點(diǎn)圖(Scatter Chart),通常是一橫一豎兩個(gè)坐標(biāo)軸,數(shù)據(jù)是一組二維坐標(biāo),分別對(duì)應(yīng)兩個(gè)坐標(biāo)軸,與坐標(biāo)軸對(duì)應(yīng)的地方打上點(diǎn)。由此可以猜到,需要的元素包括circle(圓)和axis(坐標(biāo)軸),接下來通過本文大家分享D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的散點(diǎn)圖 (V3版本) ,一起看看2019-05-05基于React的狀態(tài)管理實(shí)現(xiàn)一個(gè)簡(jiǎn)單的顏色轉(zhuǎn)換器
這篇文章主要介紹了用React的狀態(tài)管理,簡(jiǎn)簡(jiǎn)單單實(shí)現(xiàn)一個(gè)顏色轉(zhuǎn)換器,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-08-08React useMemo與useCallabck有什么區(qū)別
useCallback和useMemo是一樣的東西,只是入?yún)⒂兴煌?,useCallback緩存的是回調(diào)函數(shù),如果依賴項(xiàng)沒有更新,就會(huì)使用緩存的回調(diào)函數(shù);useMemo緩存的是回調(diào)函數(shù)的return,如果依賴項(xiàng)沒有更新,就會(huì)使用緩存的return2022-12-12React css-in-js基礎(chǔ)介紹與應(yīng)用
隨著React、Vue等支持組件化的MVVM前端框架越來越流行,在js中直接編寫css的技術(shù)方案也越來越被大家所接受。為什么前端開發(fā)者們更青睞于這些css-in-js的方案呢,下面帶你了解它2022-09-09React開發(fā)進(jìn)階redux saga使用原理詳解
這篇文章主要為大家介紹了React開發(fā)進(jìn)階redux saga使用原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11React?Native?的動(dòng)態(tài)列表方案探索詳解
這篇文章主要為大家介紹了React?Native?的動(dòng)態(tài)列表方案探索示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09