[譯]React16帶來了什麼以及對Fiber的解釋
- 原文地址:What’s New in React 16 and Fiber Explanation
- 原文作者:Trey Huffine
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:yoyoyohamapi
- 校對者:Tina92 sunui
特性概覽 —— 萬眾期待的 React 16
React 核心演算法的更新已經進行了多年了 —— 這次更新提供了一個從底層重寫了 React 的 reconciliation 演算法(譯註:reconciliation 演算法,是 React 用來比較兩棵 DOM 樹差異、從而覺得哪一部分應當被更新的演算法)。React將維護相同的公共API,並允許大多數專案立即升級(假設您已經修復了棄用警告)。新版本的釋出主要有如下目的:
-
能夠將渲染流程中可中斷的工作(interruptible work)換劃分為一個個的 chunk。
-
能夠為渲染流程中的工作提供優先順序劃分,rebase 以及重用能力。
-
在渲染流程中,能夠自如地在父子元件中切換,這使得在 React 實現 layout 成為了可能。
-
能夠從
render()
函式返回多個 element。 -
對 error boundary 提供了更好的支援。
特性
核心演算法重寫
這次演算法重寫帶來的主要特性是非同步渲染。(注意:在 16.0 中尚不支援,但是在未來的 16.x 版本中將會做為可選特性)。另外,新的重寫刪除了一些不成熟的、妨礙了內部變化的抽象。
這些多來自於 Lin Clark 的演講,所以你可以看看這個演講,再在 twitter 上 關注並點贊 Clark 來支援她這個視角獨特的概述。
非同步渲染的意義在於能夠將渲染任務劃分為多塊。瀏覽器的渲染引擎是單執行緒的,這意味著幾乎所有的行為都是同步發生的。React 16 使用原生的瀏覽器 API 來間歇性地檢查當前是否還有其他任務需要完成,從而實現了對主執行緒和渲染過程的管理。在 Firefox 中,一個瀏覽器主執行緒的例子很簡單:
while (!mExiting) {
NS_ProcessNextEvent(thread);
}
在之前的版本中,React 會在計算 DOM 樹的時候鎖住整個執行緒。這個 reconciliation 的過程現在被稱作 “stack reconciliation”。儘管 React 已經是以快而聞名了,但是鎖住整個執行緒也會讓一些應用執行得不是很流暢。16 這個版本通過不要求渲染過程在初始化後一次性完成修復了該問題。React 計算了 DOM 樹的一部分,之後將暫停渲染,來看看主執行緒是否有任何的繪圖或者更新需要去完成。一旦繪圖和更新完成了,React 就會繼續渲染。這個過程通過引入了一個新的,叫做 “fiber” 的資料結構完成,fiber 對映到了一個 React 例項併為該例項管理其渲染任務,它也知道它和其他 fiber 之間的關係。一個 fiber 僅僅是一個 JavaScript 物件。下面的圖片對比了新舊渲染方法。
React 16 也會在必要的時候管理各個更新的優先順序。這就允許了高優先順序更新能夠排到佇列開頭從而被首先處理。關於此的一個例子就是按鍵輸入。鑑於應用流暢性的考慮,使用者需要立即獲得按鍵響應,因而相對於那些可以等待 100-200 毫秒的低優先順序更新任務,按鍵輸入擁有較高優先順序。
通過將 UI 的更新劃分為若干小的工作單元,使用者體驗獲得了提高。暫停 reconciliation 任務來允許主執行緒執行其他緊急的任務,這提供了更平滑的介面和可感知到的效能提升。
錯誤處理
在 React 中,錯誤總是難於處理,但在 React 16 中,一切發生了變化。之前版本中,元件內部發生的錯誤將汙染 React 的狀態,並且在後續的渲染中引起更多含義模糊的錯誤。
React 16 含有的 error boundary 不只能夠提供清晰的錯誤資訊,還能防止整個應用因錯誤而崩潰。將 error boundary 新增到你的應用之後,它能夠 catch 住錯誤並且展示一個對應的 UI 而不會造成整個元件樹崩潰。boundary 能夠在組建的渲染期、生命週期方法及所有其子樹的構造方法中 catch 錯誤。error boundary 通過一個新的生命週期方法 componentDidCatch(error, info) 就可以輕鬆實現。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// 展示一個回退 UI
this.setState({ hasError: true });
// 你也可以將錯誤日誌輸出到一個錯誤報告服務
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// 你可以渲染任意的自定義回退 UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
在該例子中,任何發生在 <MyWidget/>
或者其子元件中的錯誤都能被 <ErrorBoundary>
元件所捕獲。這個功能類似於 JavaScript 中的 catch {}
塊。如果 error boundary 收到了一個錯誤狀態,作為開發者的你能夠確定此時應當展示的 UI。注意到 error boundary 只會 catch 其子樹的錯誤,但不會識別自身的錯誤。
進一步,你能看到如下健全的、可控的錯誤資訊:
相容性
非同步渲染
React 16.0 的初始版本將聚焦於對現有應用的相容性。非同步渲染不會再一開始作為一個可選項,但是在之後的 16.x 的版本中,非同步渲染會作為一個可選特性。
瀏覽器相容性
React 16 依賴於 Map
及 Set
。為了確保對所有瀏覽器相容,你需要要引入相關 polyfill。目前流行的 polyfill 可選 core-js 或 babel-polyfill。
另外,React 16 也依賴於 requestAnimationFrame
,這個依賴主要服務於測試。一個針對測試目的的 shim 可以是:
global.requestAnimationFrame = function(callback) {
setTimeout(callback);
};
元件宣告週期
由於 React 實現了渲染的優先順序設定,你無法再確保不同元件的 componentWillUpdate
和shouldComponentUpdate
會按期望的順序被呼叫。React 團隊目前正致力於提供一個更新路徑,來防止這些應用受到上面的行為的影響。
使用
截止到本文釋出,目前的 React 16 還處於 beta 版本,但是很快它就會正式釋出。你可以通過下面的方式嘗試 React 16:
# yarn
yarn add react@next react-dom@next
# npm
npm install --save react@next react-dom@next
如果你覺得本文對你很有用,請給我一個 。 在 Medium 上關注我,你能閱讀更多關於 React、Nonde.js、JavaScript 和開源軟體的文章。你也可以在 Twitter 或者 gitconnected找到我。
gitconnected —— 一個軟體開發者和工程師的社群。建立一個賬戶並登陸 gitconnected,這是一個當前最大的溝通開發者的社群。這是它的最新地址 gitconnected.com
相關文章
- React16——看看setState過程中fiber幹了什麼事情React
- 【譯】為什麼 React16 對開發人員來說是一種福音React
- 「譯」如何以及為什麼 React Fiber 使用連結串列遍歷元件樹React元件
- 區塊鏈現在帶來了什麼區塊鏈
- 精讀《Serverless 給前端帶來了什麼》Server前端
- 智慧家居給年輕人帶來了什麼?
- 孩子長大了能給父母帶來什麼?
- React的新引擎—React Fiber是什麼?React
- TPM給製造業帶來了什麼樣的改變?
- 微信小程式的出現給前端帶來了什麼微信小程式前端
- 收益 or 挑戰?Serverless 究竟給前端帶來了什麼Server前端
- ARKit2.0究竟給我們帶來了什麼
- 如何以及為什麼React Fiber使用連結串列遍歷元件樹React元件
- 本地生活小程式突出重圍,對商家和運營者帶來了什麼效果?
- 我學習的程式設計,都給我帶來了什麼?程式設計
- 精益生產諮詢為公司帶來了什麼?
- 衛星通訊,給手機市場帶來了什麼?
- 5G給區塊鏈開發帶來了什麼區塊鏈
- 大資料的發展,給我們生活帶來了什麼影響?大資料
- 星際迷航的序曲:“離子風”無人機究竟帶來了什麼?無人機
- react16常見api以及原理剖析ReactAPI
- [譯] 帶你瞭解什麼是工程師和工程師的影響力工程師
- 人工智慧不斷髮展,帶來了什麼影響呢?人工智慧
- 企業展廳融入互動多媒體帶來了什麼
- asp.net core 3.0中Grpc.AspNetCore.Server帶來了什麼ASP.NETRPCNetCoreServer
- 引入免費OA系統對企業能帶來什麼效益
- 遊戲開發者的通關之旅,華為AGC for Games帶來了什麼?遊戲開發GCGAM
- 【譯】什麼是JavaScript generator 以及如何使用它們JavaScript
- Android 12 正式釋出!都帶來了哪些驚喜?Android
- 展廳互動滑軌屏為科普展廳帶來了什麼?
- 《動物園之星》給模擬經營遊戲帶來了什麼遊戲
- 拋卻紛爭,百度給開源世界帶來了什麼?
- 16款新品!bilibili遊戲釋出會還能帶來什麼樣的驚喜?遊戲
- 夏普Android旗艦機來了!又會帶給什麼樣的「瀏海」樂趣?Android
- [譯] Babel 7.0 帶來的很酷的事情Babel
- Java 14 可能帶來什麼新特性?Java
- 早起,能夠給我帶來什麼?
- 大資料應用帶來了機遇與便利,也帶來了使用者對自身隱私安全的擔憂。大資料
- DevOps是什麼?DevOps能夠給我們帶來什麼?dev