React16.x特性剪輯

image

本文整理了 React 16.x 出現的耳目一新的概念與 api 以及應用場景。

更多 React 系列文章可以訂閱blog

16.0 Fiber

在 16 之前的版本的渲染過程可以想象成一次性潛水 30 米,在這期間做不了其它事情(Stack Reconciler);

image

痛點概括:

  • 一次性渲染到底
  • 中途遇到優先級更高的事件無法調整相應的順序

在 16 版本上, React 帶來了 Fiber 的架構, 接著拿上面的潛水例子為例,現在變為可以每次潛 10 米,分 3 個 chunk 進行; chunk 和 chunk 之間通過鏈表連接; chunk 間插入優先級更高的任務, 先前的任務被拋棄。

image

開啟 Fiber 后,獲取異步數據的方法應放到 render 后面的生命周期鉤子里(phase 2 階段)進行, 因為 render 前面的生命周期鉤子(phase 1階段)會被執行多次

注意: 并沒有縮短原先組件的渲染時間(甚至還加長了),但用戶卻能感覺操作變流暢了。

render()

在 React16 版本中 render() 增加了一些返回類型,到目前為止支持的返回類型如下:

  • React elements.
  • Arrays and fragments.
  • Portals.
  • String and numbers.
  • Booleans or null.

render

其中 render() 支持返回 Arrays 能讓我們少寫一個父節點, 如下所示:

const renderArray = () => [
  <div>A</div>
  <div>B</div>
]

個人認為 render() 支持返回數組完全可以取代 Fragments

Portals(傳送門)

將 react 子節點渲染到指定的節點上

案例:實現一個 Modal 組件,demo

另外關于 Portals 做到冒泡到父節點的兄弟節點這個現象, demo, 我想可以這樣子實現:如果組件返回是 Portal 對象,則將該組件的父組件的上的事件 copy 到該組件上。其實并不是真的冒泡到了父節點的兄弟節點上。

Error Boundaries

React 16 提供了一個新的錯誤捕獲鉤子 componentDidCatch(error, errorInfo), 它能將子組件生命周期里所拋出的錯誤捕獲, 防止頁面全局崩潰。demo

componentDidCatch 并不會捕獲以下幾種錯誤

  • 事件機制拋出的錯誤(事件里的錯誤并不會影響渲染)
  • Error Boundaries 自身拋出的錯誤
  • 異步產生的錯誤
  • 服務端渲染

服務端渲染

服務端渲染一般是作為最后的優化手段, 這里淺顯(缺乏經驗)談下 React 16 在其上的優化。

在 React 16 版本中引入了 React.hydrate(), 它的作用主要是將相關的事件注水html 頁面中, 同時會比較前端生成的 html 和服務端傳到前端的 html 的文本內容的差異, 如果兩者不一致將前端產生的文本內容替換服務端生成的(忽略屬性)。

支持自定義屬性

在 React 16 版本中, 支持自定義屬性(推薦 data-xxx), 因而 React 可以少維護一份 attribute 白名單, 這也是 React 16 體積減少的一個重要因素。

life cycle

在 React 16.3 的版本中,新加入了兩個生命周期:

  • getDerivedStateFromProps(nextProps, prevState): 更加語義化, 用來替代 componentWillMount、componentWillReceiveProps(nextProps);

  • getSnapshotBeforeUpdate(prevProps, prevState): 可以將結果傳入 componentDidUpdate 里, 從而達到 dom 數據統一。用來替代 componentWillUpdate()(缺點是 React 開啟異步渲染后,componentWillUpdate() 與 componentDidUpdate() 間獲取的 dom 會不統一;

16.7 Hooks

在 React 16.7 之前,React 有兩種形式的組件,有狀態組件(類)和無狀態組件(函數)。Hooks 的意義就是賦能先前的無狀態組件,讓之變為有狀態。這樣一來更加契合了 React 所推崇的函數式編程。

接下來梳理 Hooks 中最核心的 2 個 api, useStateuseEffect

useState

useState 返回狀態和一個更新狀態的函數

const [count, setCount] = useState(initialState)

使用 Hooks 相比之前用 class 的寫法最直觀的感受是更為簡潔

function App() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

useEffect(fn)

在每次 render 后都會執行這個鉤子。可以將它當成是 componentDidMountcomponentDidUpdatecomponentWillUnmount 的合集。因此使用 useEffect 比之前優越的地方在于:

  1. 可以避免在 componentDidMount、componentDidUpdate 書寫重復的代碼;
  2. 可以將關聯邏輯寫進一個 useEffect;(在以前得寫進不同生命周期里);

在上述提到的生命周期鉤子之外,其它的鉤子是否在 hooks 也有對應的方案或者舍棄了其它生命周期鉤子, 后續進行觀望。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容

  • 作為一個合格的開發者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,466評論 1 33
  • 40、React 什么是React?React 是一個用于構建用戶界面的框架(采用的是MVC模式):集中處理VIE...
    萌妹撒閱讀 1,031評論 0 1
  • 你還在為該使用無狀態組件(Function)還是有狀態組件(Class)而煩惱嗎?——擁有了hooks,你再也不需...
    水落斜陽閱讀 82,342評論 11 100
  • 我在夜里 往暗處走 腳步碎了一地 驚動了草叢 兩只眼睛對峙 心跳安撫慌亂 我們不期而遇
    三聞魚r閱讀 123評論 2 4
  • 今天還是要說關于演講的事兒,確切說,是昨晚演講比賽的續篇。 昨晚寫完了簡書,躺在腦子里復盤昨晚...
    歡樂V英雄閱讀 445評論 0 0