<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
該文章翻譯自官網 https://reactjs.org/docs/error-boundaries.html 該文章包含以下內容:
1.Error Boundaries介紹
2.ComponentDidCatch 函數的引數
3.觸發error boundaries後程式要走向哪裡?
4.對於不能捕獲的錯誤的新處理方式
5.在堆中跟蹤component
6.try/catch 如何?
7.Event Handlers怎麼樣?
8.React 15後的函數命名改變
在過去,React元件中的js錯誤通常會汙染React的內部state並且造成它發出一個讓人難以理解的錯誤給下一個Render,我們在控制檯看到的異常往往是由更內層的程式程式碼引起的,但是React並沒有提供一個方式讓我們在元件中優雅的解決他們並恢復業務邏輯。
UI的某部分引起的JS錯誤不應該破壞整個程式,為了幫React的使用者解決這個問題,React 16介紹了一種關於錯誤邊界(error boundary)的新觀念。
error boundaries 讓react元件可以捕獲在他們子級元件樹任何地方的錯誤,並且列印出這些錯誤和演示一個預備UI(fallback UI),從而替換那些出現異常的元件樹。Error boundaries在rendering,lifeCyclemethod或處於他們樹層級之下的建構函式中捕獲錯誤。
(註釋:lifecycle method是react固有名詞,包括componentWillUpdate,componentWillReceiveProps,render等方法,這些方法會自動呼叫)
注意: error boundaries並不會捕捉這些錯誤:
1.事件處理器
2.非同步程式碼
3.伺服器端的渲染程式碼
4.在error boundaries區域內的錯誤
在這個lifecycle method: componentDIdCatch(error,info) 裡的類會變成一個 error boundary
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { // Display fallback UI this.setState({ hasError: true }); // You can also log the error to an error reporting service logErrorToMyService(error, info); } render() { if (this.state.hasError) { // You can render any custom fallback UI return <h1>Something went wrong.</h1>; } return this.props.children; } }
然後你就可以像一個普通元件一樣使用它
<ErrorBoundary> <MyWidget /> </ErrorBoundary>
componentDidCatch()方法像JS的catch{}模組一樣工作,但是對於元件,只有class型別的元件(class component)可以成為一個error boundaries,在實際上,大多數情況下你可能只需要在整個程式中定義一個error boundary元件,然後你就可以一直使用它了!
請注意error boundaries僅僅可以捕獲到在他們樹的層級下面的錯誤,而不能捕獲到本層級的錯誤,如果一個error boundaries渲染錯誤資訊失敗了,那麼這個錯誤將會傳播到一個在它層級上面,並且離它最近的error boundary 。這就像js的{}模組的工作機制一樣。
componentDidCatch(error, info) { /* Example stack information: in ComponentThatThrows (created by App) in ErrorBoundary (created by App) in div (created by App) in App */ logComponentStackToMyService(info.componentStack);
關於error boundaries的後續處理由你做主,你可能會指定一個最高等級的路由元件去給使用者標識某些地方出了問題,就像伺服器端的框架處理異常一樣,你也可以指定一個在錯誤邊界內的個人的小頁面讓整個程式不至於發生崩潰。
這種變化有一個重要的新含義,對於React 16,沒有被任何error boundary捕獲的錯誤將會導致整個React元件樹的崩潰。
我們對這個決定有爭論,但是在我們的經驗裡,留下一個崩潰的UI介面比完全移除它要糟糕,例如,在一個產品比如聊天器中,留下一個崩壞的UI介面可能會導致某個人傳送資訊給一個並非他想要傳送的人。同樣的,對於一個支付類的app來說,不要顯示任何東西顯然比顯示一個錯誤的金額數目要好。
這個改動意味著如果你遷移到React 16,你可能會發現一些以前沒有注意到的,並且是確確實實存在的在你程式中的異常,增加error boundaries會讓你在某些地方出現問題的時候可以提供更好的使用者體驗。
舉個例子,facebook的側邊欄,資訊面板,對話記錄以及訊息輸入框處於被分割開來的error boundaries中,如果在他們的UI子元件中發生了崩潰事件,那麼其他的元件還可以正常執行。
我們同樣鼓勵你使用JS 錯誤報道服務(或者你自己建立一個),然後你就可以瞭解到這些未被處理的異常是如何發生的,接著解決他們。
React 16 會把所有render過程中發生的錯誤列印給開發者,即使程式意外的包含了它。它不僅僅提供了錯誤資訊和追蹤js堆,也提供了元件的堆路徑,現在你可以精確的看到元件樹中錯誤發生的地方。
你同樣可以在元件的堆追蹤中看到檔案名字和行數,這是creat react app專案的預設設定
如果你沒有使用Create React App ,你也可以通過新增這個外掛,手動的管理你的babel設定。注意:它必須嚴格的限制在開發過程中使用,生產過程一定要剔除。
注意: 在堆的追蹤中看到的元件名字取決於 Function.name屬性。如果你想要支援那些現在還沒有原生提供這些的瀏覽器和裝置,比如ie11,consider including a Function.name
polyfill in your bundled application, such as function.name-polyfill
. 否則,你必須明確的在你所有的元件中都設定displayName.
try/catch是非常棒的但是它只在imperative code(命令式程式碼)中起作用
try { showButton(); } catch (error) { // ... }
然而,react元件是宣告式的並且指定應該被渲染的內容
<Button />
Error boundaries保留了React的宣告式性質,並且擁有你期待的表現。比如,即使通過某個在樹的深層setState,在componentDidUpdate攔截中發生了錯誤,它也仍然會被正確的傳送到最近的error boundary。
error boundaries並不能捕獲event handles中的異常。
React並不需要error boundaries從event handles中恢復錯誤。與render方法和lifecycle攔截不同的是,event Handles並不會在rendering期間發生。所以如果他們被丟擲,React仍然知道怎麼去渲染。
如果你需要捕獲event handler,使用普通的js程式碼try/catch 宣告
class MyComponent extends React.Component { constructor(props) { super(props); this.state = { error: null }; } handleClick = () => { try { // Do something that could throw } catch (error) { this.setState({ error }); } } render() { if (this.state.error) { return <h1>Caught an error.</h1> } return <div onClick={this.handleClick}>Click Me</div> } }
注意以上程式碼僅僅展示通常的js習慣,而沒有使用error boundaries。
React 15通過unstable_handleError方法
包含了一些有限的error boundaries支援。這個方法現在已經不能運用,你需要使用compoentDIdCatch。
到此這篇關於react進階教學之例外處理機制error Boundaries的文章就介紹到這了,更多相關react例外處理機制error Boundaries內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45