React16.x特性剪輯

image

本文整理了 React 16.x 出現(xiàn)的耳目一新的概念與 api 以及應(yīng)用場(chǎng)景。

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

16.0 Fiber

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

image

痛點(diǎn)概括:

  • 一次性渲染到底
  • 中途遇到優(yōu)先級(jí)更高的事件無(wú)法調(diào)整相應(yīng)的順序

在 16 版本上, React 帶來(lái)了 Fiber 的架構(gòu), 接著拿上面的潛水例子為例,現(xiàn)在變?yōu)榭梢悦看螡?10 米,分 3 個(gè) chunk 進(jìn)行; chunk 和 chunk 之間通過鏈表連接; chunk 間插入優(yōu)先級(jí)更高的任務(wù), 先前的任務(wù)被拋棄。

image

開啟 Fiber 后,獲取異步數(shù)據(jù)的方法應(yīng)放到 render 后面的生命周期鉤子里(phase 2 階段)進(jìn)行, 因?yàn)?render 前面的生命周期鉤子(phase 1階段)會(huì)被執(zhí)行多次

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

render()

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

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

render

其中 render() 支持返回 Arrays 能讓我們少寫一個(gè)父節(jié)點(diǎn), 如下所示:

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

個(gè)人認(rèn)為 render() 支持返回?cái)?shù)組完全可以取代 Fragments

Portals(傳送門)

將 react 子節(jié)點(diǎn)渲染到指定的節(jié)點(diǎn)上

案例:實(shí)現(xiàn)一個(gè) Modal 組件,demo

另外關(guān)于 Portals 做到冒泡到父節(jié)點(diǎn)的兄弟節(jié)點(diǎn)這個(gè)現(xiàn)象, demo, 我想可以這樣子實(shí)現(xiàn):如果組件返回是 Portal 對(duì)象,則將該組件的父組件的上的事件 copy 到該組件上。其實(shí)并不是真的冒泡到了父節(jié)點(diǎn)的兄弟節(jié)點(diǎn)上。

Error Boundaries

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

componentDidCatch 并不會(huì)捕獲以下幾種錯(cuò)誤

  • 事件機(jī)制拋出的錯(cuò)誤(事件里的錯(cuò)誤并不會(huì)影響渲染)
  • Error Boundaries 自身拋出的錯(cuò)誤
  • 異步產(chǎn)生的錯(cuò)誤
  • 服務(wù)端渲染

服務(wù)端渲染

服務(wù)端渲染一般是作為最后的優(yōu)化手段, 這里淺顯(缺乏經(jīng)驗(yàn))談下 React 16 在其上的優(yōu)化。

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

支持自定義屬性

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

life cycle

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

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

  • getSnapshotBeforeUpdate(prevProps, prevState): 可以將結(jié)果傳入 componentDidUpdate 里, 從而達(dá)到 dom 數(shù)據(jù)統(tǒng)一。用來(lái)替代 componentWillUpdate()(缺點(diǎn)是 React 開啟異步渲染后,componentWillUpdate() 與 componentDidUpdate() 間獲取的 dom 會(huì)不統(tǒng)一;

16.7 Hooks

在 React 16.7 之前,React 有兩種形式的組件,有狀態(tài)組件(類)和無(wú)狀態(tài)組件(函數(shù))。Hooks 的意義就是賦能先前的無(wú)狀態(tài)組件,讓之變?yōu)橛袪顟B(tài)。這樣一來(lái)更加契合了 React 所推崇的函數(shù)式編程。

接下來(lái)梳理 Hooks 中最核心的 2 個(gè) api, useStateuseEffect

useState

useState 返回狀態(tài)和一個(gè)更新狀態(tài)的函數(shù)

const [count, setCount] = useState(initialState)

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

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 后都會(huì)執(zhí)行這個(gè)鉤子??梢詫⑺?dāng)成是 componentDidMount、componentDidUpdate、componentWillUnmount 的合集。因此使用 useEffect 比之前優(yōu)越的地方在于:

  1. 可以避免在 componentDidMount、componentDidUpdate 書寫重復(fù)的代碼;
  2. 可以將關(guān)聯(lián)邏輯寫進(jìn)一個(gè) useEffect;(在以前得寫進(jìn)不同生命周期里);

在上述提到的生命周期鉤子之外,其它的鉤子是否在 hooks 也有對(duì)應(yīng)的方案或者舍棄了其它生命周期鉤子, 后續(xù)進(jìn)行觀望。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容