react如何實現hooks?必須依賴 Fiber 么?( 二 )


因為它主要考慮的是體積的極致(只有 3kb) , 而不是性能的極致 。

react如何實現hooks?必須依賴 Fiber 么?

文章插圖

剛才我們了解了 react 是把 hook 鏈表存放在 fiber 節點上的 , 那 preact 沒有 fiber 節點 , 會把 hook 鏈表存在哪呢?
其實也很容易想到 , fiber 只是對 vdom 做了下改造用于提升性能的 , 和 vdom 沒啥本質的區別 , 那就把 hook 存在 vdom 上不就行了?
確實 , preact 就是把 hook 鏈表放在了 vdom 上 。
比如這個有 4 個 hooks 的函數組件:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

【react如何實現hooks?必須依賴 Fiber 么?】它的實現就是在 vdom 上存取對應的 hook:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

react如何實現hooks?必須依賴 Fiber 么?

文章插圖

它沒有像 react 那樣把 hook 分為 mount 和 update 兩個階段 , 而是合并到一起處理了 。
如圖 , 它把 hooks 存在了 component.__hooks 的數組上 , 通過下標訪問 。
這個 component 就是 vdom 上的一個屬性:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

也就是把 hooks 的值存在了 vnode._component._hooks 的數組上 。
對比下 react 和 preact 實現 hooks 的差異:
    react 中是把 hook 鏈表存放在 fiberNode.memorizedState 屬性上 , preact 中是把 hook 鏈表存放在 vnode._component._hooks 屬性上
    react 中的 hook 鏈表通過 next 串聯 , preact 中的 hook 鏈表就是個數組 , 通過下標訪問
    react 把 hook 鏈表的創建和更新分離開 , 也就是 useXxx 會分為 mountXxx 和 updateXxx 來實現 , 而 preact 中合并在一起處理的
所以說 , hooks 的實現并不依賴 fiber , 它只不過是找個地方存放組件對應的 hook 的數據 , 渲染時能取到就行 , 存放在哪里是無所謂的 。
因為 vdom、fiber 和組件渲染強相關 , 所以存放在了這些結構上 。
像 react ssr 實現 hooks , 就既沒有存在 fiber 上 , 也沒有存在 vdom 上:
react ssr 如何實現 hooks其實 react-dom 包除了可以做 csr 外 , 也可以做 ssr:
csr 時使用 react-dom 的 render 方法:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

ssr 的時候使用 react-dom/server 的 renderToString 方法或 renderToStream 方法:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

大家覺得 ssr 的時候會做 vdom 到 fiber 的轉換么?
肯定不會呀 , fiber 是為了提高在瀏覽器中運行時的渲染性能 , 把計算變成可打斷的 , 在空閑時做計算 , 才引入的一種結構 。
服務端渲染自然就不需要 fiber 。
不需要 fiber 的話 , 它把 hook 鏈表存放在哪里呢?vdom 么?
確實可以放在 vdom , 但是其實并沒有 。
比如 useRef 這個 hooks:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

它是從 firstWorkInProgressHook 開始的用 next 串聯的一個鏈表 。
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

而 firstWorkInProgressHook 最開始用 createHook 創建的第一個 hook 節點:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

并沒有掛載到 vdom 上 。
為什么呢?
因為 ssr 只需要渲染一次呀 , 又不需要更新 , 自然沒必要掛到 vdom 上 。
只要每次處理完每個組件的 hooks 就清空一下這個 hook 鏈表就行:
react如何實現hooks?必須依賴 Fiber 么?

文章插圖

react如何實現hooks?必須依賴 Fiber 么?

文章插圖

react如何實現hooks?必須依賴 Fiber 么?

文章插圖

所以 , react ssr 時 , hooks 是存在全局變量上的 。
對比下 react csr 和 ssr 時的 hooks 實現原理的區別: