目錄
#react 如何實作hooks
preact 如何實作hooks
react ssr 如何實作hooks
midway 如何實現hooks
總結
首頁 web前端 js教程 react如何實作hooks?必須依賴 Fiber 麼?

react如何實作hooks?必須依賴 Fiber 麼?

Apr 20, 2022 pm 08:52 PM
react

react如何實作hooks? React Hooks 的實作必須依賴 Fiber 麼?以下這篇文章帶大家來看看不同框架中的 hooks 都是怎麼實現的,希望對大家有幫助!

react如何實作hooks?必須依賴 Fiber 麼?

React 的hooks 是在fiber 之後出現的特性,所以很多人誤以為hooks 是必須依賴fiber 才能實現的,其實並不是,它們倆沒啥必然聯繫。 【相關推薦:Redis影片教學

現在,不只react 中實作了hooks,在preact、react ssr、midway 等框架中也實作了這個特性,它們的實作就是不依賴fiber 的。

我們分別來看一下這些不同框架中的hooks 都是怎麼實現的:

#react 如何實作hooks

react 是透過jsx 來描述介面的,它會被babel 或tsc 等編譯工具編譯成render function,然後執行產生vdom:

react如何實作hooks?必須依賴 Fiber 麼?

這裡的render function 在React17 之前是React.createElement:

react如何實作hooks?必須依賴 Fiber 麼?

在React 17 之後換成了jsx:

react如何實作hooks?必須依賴 Fiber 麼?

這個jsx-runtime 會自動引入,不用像之前那樣每個元件都要保留一個React 的import 才行。

render function 執行產生vdom:

react如何實作hooks?必須依賴 Fiber 麼?

vdom 的結構是這樣的:

react如何實作hooks?必須依賴 Fiber 麼?

在React16 之前,會遞歸渲染這個vdom,並增刪改真實dom。

react如何實作hooks?必須依賴 Fiber 麼?

而在 React16 引入了 fiber 架構之後就多了一步:先把 vdom 轉成 fiber,之後再渲染 fiber。

react如何實作hooks?必須依賴 Fiber 麼?

vdom 轉 fiber 的過程叫做 reconcile,最後增刪改真實 dom 的過程叫做 commit。

為什麼要做這樣的轉換呢?

因為 vdom 只有子節點 children 的引用,沒有父節點 parent 和其他兄弟節點 sibling 的引用,這導致了要一次性遞歸把所有 vdom 節點渲染到 dom 才行,不可打斷。

萬一打斷了會怎麼樣呢?因為沒有記錄父節點和兄弟節點,那隻能繼續處理子節點,卻不能處理 vdom 的其他部分了。

所以React 才引入了這種fiber 的結構,也就是有父節點return、子節點child、兄弟節點sibling 等引用,可以打斷,因為斷了再恢復也能找到後面所有沒處理過的節點。

fiber 節點的結構是這樣的:

react如何實作hooks?必須依賴 Fiber 麼?

這個過程可以打斷,自然就可以調度,也就是 schdule 的過程。

所以 fiber 架構就分為了 schdule、reconcile(vdom 轉 fiber)、commit(更新到 dom)三個階段。

函數元件內可以用 hooks 來存取一些值,這些值就是存在 fiber 節點上的。

例如這個函數元件內用到了6 個hook:

react如何實作hooks?必須依賴 Fiber 麼?

那麼對應的fiber 節點上就有個6 個元素的memorizedState 鍊錶:

react如何實作hooks?必須依賴 Fiber 麼?

透過next 串連起來:

1react如何實作hooks?必須依賴 Fiber 麼?

#不同的hook 在memorizedState 鍊錶不同的元素上存取值,這就是react hooks 的原理。

這個鍊錶有創建階段和更新階段,所以你會發現useXxx 的最終實作都分成了mountXxx 和updateXxx:

1react如何實作hooks?必須依賴 Fiber 麼?

這裡的mount 階段就是建立hook 節點並組裝成鍊錶的:

1react如何實作hooks?必須依賴 Fiber 麼?

會把創造好的hook 鍊錶掛到fiber 節點的memorizedState 屬性上。

那更新的時候自然也就能從fiber 節點上取出這個hook 鍊錶:

1react如何實作hooks?必須依賴 Fiber 麼?

這樣在多次渲染中,useXxx 的api 都能在fiber 節點上找到對應的memorizedState。

這就是 react hooks 的原理,可以看到它是把 hook 存在 fiber 節點上的。

那 preact 有什麼不同呢?

preact 如何實作hooks

preact 是相容react 程式碼的更輕量級的框架,它支援class 元件和function 元件,也支援了hooks 等react 特性。不過它沒有實作 fiber 架構。

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

1react如何實作hooks?必須依賴 Fiber 麼?

剛才我們了解了 react 是把 hook 鍊錶存放在 fiber 節點上的,那 preact 沒有 fiber 節點,會把 hook 鍊錶存在哪呢?

其實也很容易想到,fiber 只是對 vdom 做了下改造用於提升性能的,和 vdom 沒啥本質的區別,那就把 hook 存在 vdom 上不就行了?

確實,preact 就是把 hook 鍊錶放在了 vdom 上。

例如這個有4 個hooks 的函式元件:

1react如何實作hooks?必須依賴 Fiber 麼?

#它的實作就是在vdom 上存取對應的hook:

1react如何實作hooks?必須依賴 Fiber 麼?

1react如何實作hooks?必須依賴 Fiber 麼?

它沒有像react 那樣把hook 分成mount 和update 兩個階段,而是合併到一起處理了。

如圖,它把 hooks 存在了 component.__hooks 的陣列上,透過下標存取。

這個 component 就是 vdom 上的一個屬性:

1react如何實作hooks?必須依賴 Fiber 麼?

#也就是把 hooks 的值存在了 vnode._component._hooks 的陣列上。

對比下react 與preact 實作hooks 的差異:

  • react 中是把hook 鍊錶存放在fiberNode.memorizedState 屬性上,preact 中是把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 方法:

2react如何實作hooks?必須依賴 Fiber 麼?

大家覺得ssr 的時候會做vdom 到fiber 的轉換麼?

肯定不會呀,fiber 是為了提高在瀏覽器中運行時的渲染性能,把計算變成可打斷的,在空閒時做計算,才引入的一種結構。

服務端渲染自然就不需要 fiber。

不需要 fiber 的話,它把 hook 鍊錶存放在哪裡呢? vdom 麼?

確實可以放在 vdom,但其實並沒有。

例如 useRef 這個 hooks:

2react如何實作hooks?必須依賴 Fiber 麼?

它是從 firstWorkInProgressHook 開始的一個用 next 串連的一個鍊錶。

2react如何實作hooks?必須依賴 Fiber 麼?

而firstWorkInProgressHook 最開始用createHook 建立的第一個hook 節點:

2react如何實作hooks?必須依賴 Fiber 麼?

並沒有掛載到vdom上。

為什麼呢?

因為 ssr 只需要渲染一次呀,又不需要更新,自然沒必要掛到 vdom 上。

只要每次處理完每個元件的 hooks 就清空一下這個 hook 鍊錶就行:

2react如何實作hooks?必須依賴 Fiber 麼?

2react如何實作hooks?必須依賴 Fiber 麼?

2react如何實作hooks?必須依賴 Fiber 麼?

所以,react ssr 時,hooks 是存在全域變數上的。

對比下react csr 和ssr 時的hooks 實作原理的差異:

  • csr 時會從vdom 建立fiber,用來把渲染變成可打斷的,透過空閒調度來提高效能,而ssr 時不會,是vdom 直接渲染的

  • csr 時把hooks 保存到了fiber 節點上,ssr 時是直接放在了全局變量上,每個組件處理完就清空。因為不會用第二次了

  • csr 時會把hook 的建立和更新分成mount 和update 兩個階段,而ssr 因為只會處理一次,只有創建階段

hooks 的實作原理其實不複雜,就是在某個上下文中存放一個鍊錶,然後hooks api 從鍊錶不同的元素上存取對應的資料來完成各自的邏輯。這個上下文可以是 vdom、fiber 甚至是全域變數。

不過hooks 這個想法還是挺火的,淘寶出的服務端框架midway 就在引入了hooks 的思想:

midway 如何實現hooks

#midway 是Node.js 框架:

2react如何實作hooks?必須依賴 Fiber 麼?

服務端框架自然就沒有vdom、fiber 這種結構,不過hooks 的想法並不依賴這些,實作hooks 的api 只需要在某個上下文放一個鍊錶就行。

midway 就實作了類似react hooks 的api:

2react如何實作hooks?必須依賴 Fiber 麼?

react如何實作hooks?必須依賴 Fiber 麼?

具體它這個hook 鍊錶存在哪我還沒看,不過我們已經掌握hooks 的實作原理了,只要有個上下文存放hook 鍊錶就行,在哪都可以。

總結

react hooks 是在react fiber 架構之後出現的特性,很多人誤以為hooks 必須配合fiber 才能實現,我們分別看了react、preact、 react ssr、midway 中的hooks 的實現,發現並不是這樣的:

  • react 是把vdom 轉成fiber,然後把hook 鍊錶存放到了fiber.memorizedState 屬性上,透過next 串聯
  • preact 沒有實作fiber,它是把hook 鍊錶放到了vnode._component._hooks 屬性上,數組實現的,透過下標訪問
  • react ssr 時不需要fiber,但是也沒有把hook鍊錶掛到vdom 上,而是直接放在了一個全域變數上,因為只需要渲染一次,渲染完一個元件就清空這個全域變數就行
  • midway 是一個Node.js 框架,它也實現了hooks 類似的api,具體放在哪裡我們沒深入,但是只要有個上下文存放hook 鍊錶就行

所以,react hooks 必須依賴fiber 才能實現麼?

明顯不是,搭配 fiber、搭配 vdom、搭配全域變量,甚至任何一個上下文都可以。

更多程式相關知識,請造訪:程式設計影片! !

以上是react如何實作hooks?必須依賴 Fiber 麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何利用React和WebSocket建立即時聊天應用 如何利用React和WebSocket建立即時聊天應用 Sep 26, 2023 pm 07:46 PM

如何利用React和WebSocket建立即時聊天應用程式引言:隨著網路的快速發展,即時通訊越來越受到人們的關注。即時聊天應用程式已成為現代社交和工作生活中不可或缺的一部分。本文將介紹如何利用React和WebSocket建立一個簡單的即時聊天應用,並提供具體的程式碼範例。一、技術準備在開始建立即時聊天應用之前,我們需要準備以下技術和工具:React:一個用於構建

React前後端分離指南:如何實作前後端的解耦與獨立部署 React前後端分離指南:如何實作前後端的解耦與獨立部署 Sep 28, 2023 am 10:48 AM

React前後端分離指南:如何實現前後端的解耦和獨立部署,需要具體程式碼範例在當今的Web開發環境中,前後端分離已經成為一種趨勢。透過將前端和後端程式碼分開,可以讓開發工作更加靈活、高效,並且方便進行團隊協作。本文將介紹如何使用React實現前後端分離,從而實現解耦和獨立部署的目標。首先,我們要先理解什麼是前後端分離。傳統的Web開發模式中,前端和後端是耦合在

如何利用React和Flask建構簡單易用的網路應用 如何利用React和Flask建構簡單易用的網路應用 Sep 27, 2023 am 11:09 AM

如何利用React和Flask建構簡單易用的網路應用引言:隨著網路的發展,網路應用的需求也越來越多樣化和複雜化。為了滿足使用者對於易用性和效能的要求,使用現代化的技術堆疊來建立網路應用變得越來越重要。 React和Flask是兩個在前端和後端開發中非常受歡迎的框架,它們可以很好的結合在一起,用來建立簡單易用的網路應用。本文將詳細介紹如何利用React和Flask

如何利用React和RabbitMQ建立可靠的訊息應用 如何利用React和RabbitMQ建立可靠的訊息應用 Sep 28, 2023 pm 08:24 PM

如何利用React和RabbitMQ建立可靠的訊息傳遞應用程式引言:現代化的應用程式需要支援可靠的訊息傳遞,以實現即時更新和資料同步等功能。 React是一種流行的JavaScript庫,用於建立使用者介面,而RabbitMQ是一種可靠的訊息傳遞中間件。本文將介紹如何結合React和RabbitMQ建立可靠的訊息傳遞應用,並提供具體的程式碼範例。 RabbitMQ概述:

React Router使用指南:如何實現前端路由控制 React Router使用指南:如何實現前端路由控制 Sep 29, 2023 pm 05:45 PM

ReactRouter使用指南:如何實現前端路由控制隨著單頁應用的流行,前端路由成為了一個不可忽視的重要部分。 ReactRouter作為React生態系統中最受歡迎的路由庫,提供了豐富的功能和易用的API,使得前端路由的實作變得非常簡單和靈活。本文將介紹ReactRouter的使用方法,並提供一些具體的程式碼範例。安裝ReactRouter首先,我們需要

如何利用React和Google BigQuery建立快速的資料分析應用 如何利用React和Google BigQuery建立快速的資料分析應用 Sep 26, 2023 pm 06:12 PM

如何利用React和GoogleBigQuery建立快速的資料分析應用引言:在當今資訊爆炸的時代,資料分析已經成為了各產業中不可或缺的環節。而其中,建構快速、有效率的資料分析應用則成為了許多企業和個人追求的目標。本文將介紹如何利用React和GoogleBigQuery結合來建立快速的資料分析應用,並提供詳細的程式碼範例。一、概述React是用來構建

如何利用React與Apache Kafka建構即時資料處理應用 如何利用React與Apache Kafka建構即時資料處理應用 Sep 27, 2023 pm 02:25 PM

如何利用React和ApacheKafka來建立即時資料處理應用介紹:隨著大數據與即時資料處理的興起,建構即時資料處理應用成為了許多開發者的追求。 React作為一個流行的前端框架,與ApacheKafka作為一個高效能的分散式訊息系統的結合,可以幫助我們建立即時資料處理應用。本文將介紹如何利用React和ApacheKafka建構即時資料處理應用,並

PHP、Vue和React:如何選擇最適合的前端框架? PHP、Vue和React:如何選擇最適合的前端框架? Mar 15, 2024 pm 05:48 PM

PHP、Vue和React:如何選擇最適合的前端框架?隨著互聯網技術的不斷發展,前端框架在Web開發中起著至關重要的作用。 PHP、Vue和React作為三種代表性的前端框架,每一種都具有其獨特的特徵和優勢。在選擇使用哪種前端框架時,開發人員需要根據專案需求、團隊技能和個人偏好做出明智的決策。本文將透過比較PHP、Vue和React這三種前端框架的特徵和使

See all articles