React16.x特性剪輯

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

更多 React 系列文章能夠訂閱blog前端

16.0 Fiber

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

痛點歸納:git

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

在 16 版本上, React 帶來了 Fiber 的架構, 接着拿上面的潛水例子爲例,如今變爲能夠每次潛 10 米,分 3 個 chunk 進行; chunk 和 chunk 之間經過鏈表鏈接; chunk 間插入優先級更高的任務, 先前的任務被拋棄。github

開啓 Fiber 後,獲取異步數據的方法應放到 render 後面的生命週期鉤子裏(phase 2 階段)進行, 由於 render 前面的生命週期鉤子(phase 1階段)會被執行屢次編程

注意: 並無縮短原先組件的渲染時間(甚至還加長了),但用戶卻能感受操做變流暢了。api

render()

在 React16 版本中 render() 增長了一些返回類型,到目前爲止支持的返回類型以下:數組

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

render架構

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

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 也有對應的方案或者捨棄了其它生命週期鉤子, 後續進行觀望。

相關文章
相關標籤/搜索