最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React更新渲染原理深入分析

 更新時間:2022年12月23日 15:14:22   作者:前端開發(fā)小司機  
什么是re-render(重新渲染)?哪些是必要的re-render?哪些是非必要的re-render?如果你對這些問題還不是很明白,那么可以在這篇文章中找到答案

當我們調(diào)用 setState 之后發(fā)生了什么?react經(jīng)歷了怎樣的過程將新的 state 渲染到頁面上?

一次react更新,核心就是對虛擬dom進行diff,找出最少的需要變化的dom節(jié)點,然后對其進行相應的dom操作,用戶即可在頁面上看到更新。但 react 作為廣泛使用的框架,需要考慮更多的因素,考慮多個更新的優(yōu)先級,考慮主線程占用時長,考慮diff算法復雜度,考慮性能。。等等,本文就來探討一下react在其內(nèi)部是如何處理數(shù)據(jù)更新的。

react在內(nèi)部使用fiber這種數(shù)據(jù)結構來作為虛擬dom【react16+】,它與dom tree一一對應,形成fiber tree,一次react更新,本質(zhì)是fiber tree結構的更新變化。而fiber tree結構的更新,用更專業(yè)的術語來講,其實就是fiber tree的協(xié)調(diào)(Reconcile)。Reconcile中文意思是調(diào)和、使一致,協(xié)調(diào)fiber tree,就是調(diào)整fiber tree的結構,使其和更新后的jsx模版結構、dom tree保持一致。

react從16起,將更新機制分為三個模塊,也可以說是三個步驟,分別是Schedule【調(diào)度】、Reconcile【協(xié)調(diào)】、render【渲染】

Schedule

為什么需要Schedule?

首先我們要知道react在進行協(xié)調(diào)時,提供了兩種模式:Legacy mode 同步阻塞模式和 Concurrent mode 并行模式。

不同上下文中的更新會觸發(fā)不同的模式,如果是在 eventsetTimeout、network requestcallback 中觸發(fā)更新,react 會采用 Legacy 模式。如果更新與 Suspense、useTransitionOffScreen 相關,那么 react 會采用 Concurrent 模式。

Legacy mode

Legacy mode在協(xié)調(diào)時會啟動 workLoopSync。workLoopSync 開始工作以后,要等到所有 fiber node 都處理完畢以后,才會結束工作,也就是 fiber tree 的協(xié)調(diào)過程不可中斷。

Legacy mode存在的問題:如果 fiber tree 的結構很復雜,那么協(xié)調(diào) fiber tree 可能會占用大量的時間,導致主線程會一直被 js 引擎占用,渲染引擎無法在規(guī)定時間(瀏覽器刷新頻率 - 16.7ms)內(nèi)完成工作,使得頁面出現(xiàn)卡頓(掉幀),影響用戶體驗。

Concurrent mode

鑒于Legacy mode存在的問題,react團隊在react 16中提出了 Concurrent mode的概念,并在react 18中開放使用。react16、17一直為此做準備。

Concurrent 模式最大的意義在于,使用Concurrent 模式以后的react的應用可以做到:

  • 協(xié)調(diào)可以中斷、恢復;不會長時間阻塞瀏覽器渲染
  • 高優(yōu)先級更新可以中斷低優(yōu)先級更新,優(yōu)先渲染

那么,怎么做到這兩點呢?

事實上,Schedule就是用來完成這個任務的,調(diào)度任務的優(yōu)先級,使高優(yōu)先級任務優(yōu)先進入Reconcile,并且提供中斷和恢復機制。

時間切片

react采用時間切片的方式來實現(xiàn)協(xié)調(diào)的中斷和恢復,Concurrent mode在協(xié)調(diào)時會啟動 workLoopConcurrent。 workLoopConcurrent 開始工作以后,每次協(xié)調(diào) fiber node 時,都會判斷當前時間片是否到期。如果時間片到期,會停止當前 workLoopConcurrent,讓出主線程,然后請求下一個時間片繼續(xù)協(xié)調(diào)。

協(xié)調(diào)的中斷及恢復,類似于瀏覽器的eventloop,js引擎和渲染引擎互斥,在主線程中交替工作。

我們可以通過模擬 eventLoop來實現(xiàn)時間分片以及重新請求時間片。一段 js 程序,如果在規(guī)定時間內(nèi)沒有結束,那我們可以主動結束它,然后請求一個新的時間片,在下一個時間片內(nèi)繼續(xù)處理上一次沒有結束的任務。

let taskQueue = [];   // 任務列表
let shouldTimeEnd = 5ms;   // 一個時間片定義為 5ms
let channel = new MessageChannel();  // 創(chuàng)建一個 MessageChannel 實例
function wookLoop() {
    let beginTime = performance.now();  // 記錄開始時間
    while(true) { // 循環(huán)處理 taskQueue 中的任務
        let currentTime = performance.now();  // 記錄下一個任務開始時的時間
        if (currentTime - beginTime >= shouldTimeEnd) break;  // 時間片已經(jīng)到期,結束任務處理
        processTask();  // 時間片沒有到期,繼續(xù)處理任務
  }
    if (taskQueue.length) { // 時間片到期,通過調(diào)用 postMessage,請求下一個時間片
        channel.port2.postMessage(null); 
  }
}
channel.port1.onmessage = wookLoop;  // 在下一個時間片內(nèi)繼續(xù)處理任務
workLoop(); 

和瀏覽器的消息隊列 一樣, react 也會維護一個任務隊列 taskQueue,然后通過 workLoop 遍歷 taskQueue,依次處理 taskQueue 中的任務。

taskQueue 中收集任務是有先后處理順序的,workLoop 每次處理 taskQueue 中的任務時,都會挑選優(yōu)先級最高的任務進行處理。

每觸發(fā)一次 react 更新,意味著一次 fiber tree 的協(xié)調(diào),但協(xié)調(diào)并不會在更新觸發(fā)時立刻同步進行。相反,react 會為這一次更新,生成一個 task,并添加到 taskQueue 中,fiber tree 的協(xié)調(diào)方法會作為新建 taskcallback。當 wookLoop 開始處理該 task 時,才會觸發(fā) taskcallback,開始 fiber tree 的協(xié)調(diào)。

任務的優(yōu)先級

react在內(nèi)部定義了 5 種類型的優(yōu)先級,以及對應的超時時間timeout

  • ImmediatePriority, 直接優(yōu)先級,對應用戶的 clickinput、focus 等操作; timeout為 -1,表示任務要盡快處理;
  • UserBlockingPriority,用戶阻塞優(yōu)先級,對應用戶的 mousemove、scroll 等操作;timeout 為 250 ms;
  • NormalPriority,普通優(yōu)先級,對應網(wǎng)絡請求、useTransition 等操作; timeout 為 5000 ms;
  • LowPriority,低優(yōu)先級(未找到應用場景);timeout 為 10000 ms;
  • IdlePriority,空閑優(yōu)先級,如 OffScreen; timeout 為 1073741823 ms;

5 種優(yōu)先級的順序為: ImmediatePriority > UserBlockingPriority > NormalPriority > LowPriority > IdlePriority。

在確定了任務的優(yōu)先級以后,react 會根據(jù)優(yōu)先級為任務計算一個過期時間 expirationTime,即 expirationTime = currentTime + timeout,然后根據(jù) expirationTime 時間來決定任務處理的先后順序。

expirationTime越小的任務會被排在task隊列的越前面,之所以需要timeout,而不是直接對比優(yōu)先級等級,是為了避免低優(yōu)先級任務長時間被 插隊而導致一直無響應;同時,在時間分片到期時,需要根據(jù)expirationTime判斷下一個要處理的任務是否過期,如果已過期,就不能讓出主線程,需要立即處理。

??注:react17中用Lanes重構了優(yōu)先級算法,此處不展開陳述,有興趣的同學可查閱相關文檔。

獲取最先處理的task

react 采用了小頂堆來存儲task,實現(xiàn)最小優(yōu)先隊列,即 taskQueue 是一個小頂堆,放在堆頂?shù)?code>task是需要最先處理的。

使用最小堆時,有三個操作:push、poppeek。

push,入堆操作,即將 task 添加到 taskQueue 中。添加一個新創(chuàng)建的 task 時,會將 task 添加到最小堆的堆底,然后對最小堆做自底向上的調(diào)整。調(diào)整時,會比較堆節(jié)點(task) 的 expirationTime,將 expirationTime 較小的 task 向上調(diào)整。* peek,獲取堆頂元素,即獲取需要最先處理的 task,執(zhí)行 taskcallback,開始 fiber tree 的協(xié)調(diào)。* pop,堆頂元素出堆,即 task 處理完畢,從 taskQueue 中移除。移除堆頂元素以后,會對最小堆做自頂向下的調(diào)整。調(diào)整時,也是比較堆節(jié)點(task) 的 expirationTime,將 expirationTime 較大的 task 向下調(diào)整。### 高優(yōu)先級的更新中斷低優(yōu)先級的更新

Concurrent 模式下,如果在低優(yōu)先級更新的協(xié)調(diào)過程中,有高優(yōu)先級更新進來,那么高優(yōu)先級更新會中斷低優(yōu)先級更新的協(xié)調(diào)過程。

每次拿到新的時間片以后,workLoopConcurrent 都會判斷本次協(xié)調(diào)對應的優(yōu)先級和上一次時間片到期中斷的協(xié)調(diào)的優(yōu)先級是否一樣。如果一樣,說明沒有更高優(yōu)先級的更新產(chǎn)生,可以繼續(xù)上次未完成的協(xié)調(diào);如果不一樣,說明有更高優(yōu)先級的更新進來,此時要清空之前已開始的協(xié)調(diào)過程,從根節(jié)點開始重新協(xié)調(diào)。等高優(yōu)先級更新處理完成以后,再次從根節(jié)點開始處理低優(yōu)先級更新。

Reconcile

前面說到,reconcile(協(xié)調(diào))就是fiber tree 結構的更新,那么具體是怎樣更新的呢?本小節(jié)就來解答這個問題。

前置知識

從jsx到dom

Step1: 從jsx生成react element

jsx 模板通過 babel 編譯為 createElement 方法;執(zhí)行組件方法,觸發(fā) createElement 的執(zhí)行,返回 react element

Step2: 從react element生成fiber tree

  • fiber tree 中存在三種類型的指針 child、sibling、return。其中,child 指向第一個子節(jié)點,sibling 指向兄弟節(jié)點,return 指針指向父節(jié)點;* fiber tree 采用的深度優(yōu)先遍歷,如果節(jié)點有子節(jié)點,先遍歷子節(jié)點;子節(jié)點遍歷結束以后,再遍歷兄弟節(jié)點;沒有子節(jié)點、兄弟節(jié)點,就返回父節(jié)點,遍歷父節(jié)點的兄弟節(jié)點;* 當節(jié)點的 return 指針返回 null 時,fiber tree 的遍歷結束;Step3: fiber tree生成之后,從fiber tree到真實dom,就是處理fiber tree上對應的副作用,包括:
  • 所有 dom 節(jié)點的新增;
  • componentDidMount、useEffectcallback 函數(shù)的觸發(fā);
  • ref 引用的初始化;

雙緩存fiber tree

react 做更新處理時,會同時存在兩顆 fiber tree。一顆是已經(jīng)存在的 old fiber tree,對應當前屏幕顯示的內(nèi)容,稱為 current fiber tree;另外一顆是更新過程中構建的 new fiber tree,稱為 workInProgress fiber tree。

current fiber treeworkInProgress fiber tree可以通過alternate指針互相訪問

當更新完成以后,使用 workInProgress fiber tree 替換掉 current fiber tree,作為下一次更新的 current fiber tree。

協(xié)調(diào)的過程

協(xié)調(diào)過程中主要做三件事情:

1.為 workInProgress fiber tree 生成 fiber node

2.為發(fā)生變化的 fiber node標記副作用 effect;

3.收集帶 effectfiber node

生成workInProgress fiber tree

workInProgress fiber tree 作為一顆新樹,生成 fiber node 的方式有三種:

  • 克隆(淺拷貝) current fiber node,意味著原來的 dom 節(jié)點可以復用,只需要更新 dom 節(jié)點的屬性,或者移動 dom 節(jié)點;
  • 新建一個 fiber node,意味著需要新增加一個 dom 節(jié)點;
  • 直接復用 current fiber node,表示對應的 dom 節(jié)點完全不用做任何處理;

復用的場景:當子組件的渲染方法(類組件的 render、函數(shù)組件方法)沒有觸發(fā),(比如使用了React.memo),沒有返回新的 react element,子節(jié)點就可以直接復用 current fiber node。

在日常開發(fā)過程中,我們可以通過合理使用 ShouldComponentUpdate、React.memo,阻止不必要的組件重新 render,通過直接復用 current fiber node,加快 workInProgress fiber tree 的協(xié)調(diào),達到優(yōu)化的目的。

相反,只要組件的渲染方法被觸發(fā),返回新的 react element,那么就需要根據(jù)新的 react element 為子節(jié)點創(chuàng)建 fiber node(通過淺拷貝或新建)。

  • 如果能在 current fiber tree 中找到匹配節(jié)點,那么可以通過克隆(淺拷貝) current fiber node 的方式來創(chuàng)建新的節(jié)點;
  • 相反,如果無法在 current fiber tree 找到匹配節(jié)點,那么就需要重新創(chuàng)建一個新的節(jié)點;

我們常說的diff算法就是發(fā)生在這一環(huán)節(jié)。

diff算法比較的雙方是 workInProgress fiber tree 中用于構建 fiber nodereact elementcurrent fiber tree 中的 fiber node,比較兩者的 keytype,根據(jù)比較結果來決定如何為 workInProgress fiber tree 創(chuàng)建 fiber node。

【 key 和 type 】:

key就是 jsx 模板中元素上的 key 屬性。如果不寫默認為undefined。jsx 模板轉(zhuǎn)化為 react element 后,元素的 key 屬性會作為 react elementkey 屬性。同樣的,react element 轉(zhuǎn)化為 fiber node 以后,react elementkey 屬性也會作為 fiber nodekey 屬性。

jsx 中不同的元素類型,有不同的type

<Component name="xxxx" />  //type = Component, 是一個函數(shù)
<div></div>    // type = "div", 是一個字符串
<React.Fragment></React.Fragment>  // type = React.Fragment, 是一個數(shù)字(react 內(nèi)部定義的); 

jsx 模板轉(zhuǎn)化為 react element 以后,react elementtype 屬性會根據(jù) jsx 元素的類型賦不同的值,可能是組件函數(shù),也可能是 dom 標簽字符串,還可能是數(shù)字。 react element 轉(zhuǎn)化為 fiber node 以后,react elementtype 屬性也會作為 fiber nodetype 屬性。

綜上,判斷拷貝 current fiber node 的邏輯,概括來就是:

reactElement.key === currentFiberNode.key && reactElement.type === currentFiberNode.type, current fiber node //可以克??;
reactElement.key !== currentFiberNode.key, current fiber node //不可克?。?
reactElement.key === currentFiberNode.key && reactElement.type !== currentFiberNode.type, current fiber node //不可克?。?

diff 算法:

  • 已匹配的父節(jié)點的直接子節(jié)點進行比較,不跨父節(jié)點比較;
  • 通過比較 key、type 來判斷是否需要克隆 current fiber node。只有 keytype 都相等,才克隆 current fiber node 作為新的節(jié)點,否則就需要新建一個節(jié)點。key 值和節(jié)點類型type,key 的優(yōu)先級更高。如果 key 值不相同,那么節(jié)點不可克隆。
  • 當比較 single react elementcurrent fiber node list 時,只需要遍歷 current fiber node list,比較每個 current fiber nodereact elementkey 值和 type。只有 keytype 都相等,react elementcurrent fiber node 才能匹配。如果有匹配的,直接克隆current fiber node,作為 react element 對應的 workInProgress fiber node。如果沒有匹配的 current fiber node,就需要為 react element 重新創(chuàng)建一個新的 fiber node 作為 workInProgress fiber node。
  • 當比較react element listcurrent fiber node list 時,還需要通過列表下標 index 判斷 wokrInProgress fiber node 是否相對于克隆的 current fiber node 發(fā)生了移動。這也是diff中最復雜的地方。

為發(fā)生變化的fiber node標記effect

判斷節(jié)點是否發(fā)生變化

  • 節(jié)點只要是重新創(chuàng)建的而不是克隆自 current fiber node,那么節(jié)點就百分之百發(fā)生了變化,需要更新;* 節(jié)點克隆自 current fiber node,需要比較 props 是否發(fā)生了變化,如果 props 發(fā)生了變化,節(jié)點需要更新;* 節(jié)點克隆自 current fiber node,且是組件類型,還需要比較 state 是否發(fā)生了變化,如果 state 發(fā)生了變化,節(jié)點需要更新;常見的effect類型:
  • Placement,放置,只針對 dom 類型的 fiber node,表示節(jié)點需要做移動或者添加操作。
  • Update,更新,針對所有類型的 fiber node,表示 fiber node 需要做更新操作。
  • PlacementAndUpdate,放置并更新,只針對 dom 類型的 fiber node,表示節(jié)點發(fā)生了移動且 props 發(fā)生了變化。
  • Ref,表示節(jié)點存在 ref,需要初始化 / 更新 ref.current。
  • Deletion,刪除,針對所有類型的 fiber node,表示 fiber node 需要移除。
  • Snapshot,快照,主要是針對類組件 fiber node。當類組件 fiber node 發(fā)生了 mount 或者 update 操作,且定義了 getSnapshotBeforeUpdate 方法,就會標記 Snapshot
  • Passive,主要針對函數(shù)組件 fiber node,表示函數(shù)組件使用了 useEffect。當函數(shù)組件節(jié)點發(fā)生 mount 或者 update 操作,且使用了 useEffect hook,就會給 fiber node 標記 Passive。
  • Layout,主要針對函數(shù)組件 fiber node,表示函數(shù)組件使用了 useLayoutEffect。當函數(shù)組件節(jié)點發(fā)生 mount 或者 update 操作,且使用了 useLayoutEffect hook,就會給 fiber node 標記 Layout

react 使用二進制數(shù)來聲明 effect,如 Placement 為 2 (0000 0010),Update 為 4 (0000 0100)。一個 fiber node 可同時標記多個 effect,如函數(shù)組件 props 發(fā)生變化且使用了 useEffect hook,那么就可以使用 Placement | Update = 516(位運算符) 來標記。

收集帶effect的fiber node

如果一個 fiber node 被標記了 effect,那么 react 就會在這個 fiber node 完成協(xié)調(diào)以后,將這個 fiber node 收集到effectList中。當整顆 fiber tree 完成協(xié)調(diào)以后,所有被標記 effectfiber node 都被收集到一起。

收集fiber nodeeffectList 采用單鏈表結構存儲,firstEffect 指向第一個標記 effectfiber node,lastEffect 標記最后一個 fiber node,節(jié)點之間通過 nextEffect 指針連接。

由于 fiber tree 協(xié)調(diào)時采用的順序是深度優(yōu)先,協(xié)調(diào)完成的順序是子節(jié)點、子節(jié)點兄弟節(jié)點、父節(jié)點,所以收集帶 effect 標記的 fiber node 時,順序也是子節(jié)點、子節(jié)點兄弟節(jié)點、父節(jié)點。

Render

render也稱為commit,是對協(xié)調(diào)過程中標記的effect 的處理

effect 的處理分為三個階段,這三個階段按照從前到后的順序為:

1.before mutation 階段 (dom 操作之前)

2.mutation 階段 (dom 操作)

3.layout 階段 (dom 操作之后)

不同的階段,處理的 effect 種類也不相同。在每個階段,react 都會從 effectList 鏈表的頭部 - firstEffect 開始,按序遍歷 fiber node, 直到 lastEffect

before mutation階段

before mutation 階段的主要工作是處理帶 Snapshot 標記的 fiber node。 從 firstEffect 開始遍歷 effect 列表,如果 fiber nodeSnapshot 標記,觸發(fā) getSnapshotBeforeUpdate 方法。

mutation階段

mutation 階段的主要工作是處理帶 DeletionPlacement、PlacementAndUpdate、Update 標記的 fiber node。 在這一階段,涉及到 dom 節(jié)點的更新、新增、移動、刪除,組件節(jié)點刪除導致的 componentWillUnmount、destory 方法的觸發(fā),以及刪除節(jié)點引發(fā)的 ref 引用的重置。

dom 節(jié)點的更新:

  • 通過原生的 API setAttributeremoveArrribute 修改 dom 節(jié)點的 attr;
  • 直接修改 dom 節(jié)點的 style;
  • 直接修改 dom 節(jié)點的 innerHtml、textContent;

dom 節(jié)點的新增和移動:

  • 如果新增(移動)的節(jié)點是父節(jié)點的最后一個子節(jié)點,那么可以直接使用 appendChild 方法。
  • 如果不是最后一個節(jié)點,需要使用 insertBefore 方法。通過遍歷找到第一個沒有帶Placement標記的節(jié)點作為insertBefore的定位元素。

dom節(jié)點的刪除:

  • 如果節(jié)點是 dom 節(jié)點,通過 removeChild 移除;
  • 如果節(jié)點是組件節(jié)點,觸發(fā) componentWillUnmountuseEffectdestory 方法的執(zhí)行;
  • 如果標記 Deletion 的節(jié)點的子節(jié)點中有組件節(jié)點,深度優(yōu)先遍歷子節(jié)點,依次觸發(fā)子節(jié)點的 componentWillUnmount、useEffectdestory 方法的執(zhí)行;
  • 如果標記 Deletion 的節(jié)點及子節(jié)點關聯(lián)了 ref 引用,要將 ref 引用置空,及 ref.current = null(也是深度優(yōu)先遍歷);

layout 階段

layout 階段的主要工作是處理帶 update 標記的組件節(jié)點和帶 ref 標記的所有節(jié)點。 工作內(nèi)容如下:

  • 如果類組件節(jié)點是mount操作,觸發(fā) componentDidMount;如果是 update 操作,觸發(fā) componentDidUpdate
  • 如果函數(shù)組件節(jié)點時 mount 操作,觸發(fā) useLayoutEffectcallback;如果是 update 操作,先觸發(fā)上一次更新生成的 destory,再觸發(fā)這一次的 callback;
  • 異步調(diào)度函數(shù)組件的 useEffect;
  • 如果組件節(jié)點關聯(lián)了 ref 引用,要初始化 ref.current;

到此這篇關于React更新渲染原理深入分析的文章就介紹到這了,更多相關React更新渲染內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • React Fiber中面試官最關心的技術話題

    React Fiber中面試官最關心的技術話題

    這篇文章主要為大家介紹了React Fiber中面試官最關心的技術話題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • React Native 集成jpush-react-native的示例代碼

    React Native 集成jpush-react-native的示例代碼

    這篇文章主要介紹了React Native 集成jpush-react-native的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 解決React報錯Style prop value must be an object

    解決React報錯Style prop value must be a

    這篇文章主要為大家介紹了React報錯Style prop value must be an object解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • react中的useEffect()的使用詳解

    react中的useEffect()的使用詳解

    useEffect()是react中的hook函數(shù),作用是用于創(chuàng)建由渲染本身引起的操作,介紹了依賴項數(shù)組不同的區(qū)別,對react useEffect()使用相關知識感興趣的朋友一起看看吧
    2024-05-05
  • React中state屬性和生命周期的使用

    React中state屬性和生命周期的使用

    這篇文章主要介紹了React中state屬性和生命周期的使用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • react使用CSS實現(xiàn)react動畫功能示例

    react使用CSS實現(xiàn)react動畫功能示例

    這篇文章主要介紹了react使用CSS實現(xiàn)react動畫功能,結合實例形式分析了react使用CSS實現(xiàn)react動畫功能具體步驟與實現(xiàn)方法,需要的朋友可以參考下
    2020-05-05
  • React實現(xiàn)一個支持動態(tài)插槽的Layout組件

    React實現(xiàn)一個支持動態(tài)插槽的Layout組件

    這篇文章主要為大家詳細介紹了如何使用React實現(xiàn)一個支持動態(tài)注冊內(nèi)容的插槽組件,文中的示例代碼簡潔易懂,有需要的小伙伴可以了解一下
    2025-02-02
  • 在React中使用React.createRef:更優(yōu)雅的DOM引用方式

    在React中使用React.createRef:更優(yōu)雅的DOM引用方式

    React提供了多種方式來引用DOM元素,其中React.createRef()是一種更為現(xiàn)代、更優(yōu)雅的方式,在這篇文章中,我們將深入了解React.createRef()的應用,以及它為開發(fā)者帶來的便利,感興趣的朋友一起看看吧
    2024-01-01
  • 關于?React?中?useEffect?使用問題淺談

    關于?React?中?useEffect?使用問題淺談

    本文主要介紹了關于React中useEffect使用問題淺談,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • 用React Native制作一個簡單的游戲引擎

    用React Native制作一個簡單的游戲引擎

    今天給大家分享的是使用React Native制作一個簡單的游戲,這個游戲可以跨平臺操作,本文通過實例圖文相結合給大家介紹的非常詳細,對React Native游戲相關知識感興趣的朋友一起看看吧
    2021-05-05

最新評論

兴海县| 和政县| 仪征市| 伊川县| 灵山县| 张家口市| 定安县| 福州市| 宁海县| 三台县| 南陵县| 岗巴县| 凌云县| 大关县| 绥德县| 彭山县| 日照市| 江津市| 阳城县| 洞头县| 九江县| 南郑县| 额敏县| 云和县| 海林市| 泰兴市| 宜兰市| 永康市| 依兰县| 宁德市| 长海县| 青海省| 潮州市| 三原县| 鄂托克前旗| 兴安县| 阜南县| 湄潭县| 鸡泽县| 临颍县| 永川市|