成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

理解 React 的調(diào)和器 Reconciler

開發(fā) 前端
ReactElement 就是 React.createElement() 方法的返回結(jié)果,一種 映射真實 DOM 層級關(guān)系的對象,但里面可以帶上組件元素。通常我們會用 JSX 去寫。

大家好,我是前端西瓜哥。今天來學(xué)習(xí) React 中的調(diào)和器 Reconciler。

React 的版本為 18.2.0

ReactElement、fiber 和 Dom

ReactElement 就是 React.createElement() 方法的返回結(jié)果,一種 映射真實 DOM 層級關(guān)系的對象,但里面可以帶上組件元素。通常我們會用 JSX 去寫。

類組件的 render 方法的返回值和函數(shù)組件的返回值都是 ReactElement。

fiber 是一個節(jié)點,是 React Fiber 時間分片架構(gòu)中的一個節(jié)點。fiber 是 ReactElement 和真實 DOM 的橋梁。

fiber 會根據(jù) ReactElement 構(gòu)建成一棵樹。當更新時,組件會調(diào)用 render 方法生成新的 ReactElement,然后我們再構(gòu)建一個新的 Fiber 樹,和舊樹對比。

fiber 樹下的 fiber 節(jié)點通過下面三個字段進行關(guān)聯(lián):

  • return:父 fiber。
  • child:子 fiber 的第一個。
  • sibling :下一個兄弟節(jié)點。

一個 App 組件的 fiber 樹結(jié)構(gòu):

圖片

App 的 child 是會指向它創(chuàng)建的 element 對應(yīng) fiber 的根節(jié)點。

構(gòu)建 Fiber 樹的過程

在調(diào)用 createRoot(并發(fā)模式)或者 ReactDOM.render(同步模式)時,會執(zhí)行 createFiberRoot 方法。

function createFiberRoot(containerInfo, tag) {
// 生成 fiberRoot。containerInfo 是掛載根節(jié)點(比如 div#root)
const root = new FiberRootNode(containerInfo, tag);
// 生成 rootFiber
const uninitializedFiber = createHostRootFiber(tag);
// 互相關(guān)聯(lián)
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;

return root;
}

createFiberRoot 創(chuàng)建一個了 fiberRoot,以及一個 rootFiber。它們的關(guān)系如下:

圖片

一個 fiberRoot 是 fiber 樹的根節(jié)點的維護者,是 fiberRootNode 實例,通過 current 確定要使用哪一棵 fiber 樹。

每調(diào)用 createRoot 都會構(gòu)建新的 fiber 樹,并生成一個新的 fiberRoot 去指向它。

rootFiber 是一顆 fiber 樹的根節(jié)點,也屬于是 fiber 節(jié)點。rootFiber 通過屬性 stateNode 訪問到 fiberRoot。注意不是 return,因為 fiberRoot 的結(jié)構(gòu)完全不一樣,不是 fiber 節(jié)點。

creatRoot 方法返回的是個對象,它的 _internalRoot 屬性指向的是這個 fiberRoot。

performUnitOfWork

在 workLoopSync 或 workLoopConcurrent 中,是會不斷地調(diào)用  performUnitOfWork(workInProgress) 的。

這個函數(shù)會不斷地處理以 fiber 為單位的任務(wù)。

workLoopConcurrent 的實現(xiàn):

function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield()) {
performUnitOfWork(workInProgress);
}
}

看看 performUnitOfWork 的核心實現(xiàn):

function performUnitOfWork(unitOfWork) {
// 拿到當前 fiber 節(jié)點的 “替身”
var current = unitOfWork.alternate;
var next = beginWork(current, unitOfWork, subtreeRenderLanes); // 遞
if (next === null) {
completeUnitOfWork(unitOfWork); // 歸
} else {
workInProgress = next;
}
}

performUnitOfWork 由兩部分組成:

  1. beginWork:自上而下的調(diào)和,主要在構(gòu)建 fiber。fiber 其實是對之前架構(gòu) “遞歸” 的模擬,這個 beginWork 對應(yīng)著 “遞”。
  2. completeUnitOfWork:自下而上的合并階段。對應(yīng)遞歸的 “歸”。

還是這個 fiber 樹的圖,這里的粉色的 1、2、4 表示的是 beginWork,3、5 則代表 completeUnitOfWork。

圖片

beginWork

performUnitOfWork 中,先調(diào)用 beginWork。

beginWork 的作用是,自上而下根據(jù)組件進行組件實例化,根據(jù)新的 element 構(gòu)建 fiber,給舊的 fiber 打上 effectTag。

function beginWork(current, workInProgress, renderLanes) {
if (current !== null) {
const oldProps = current.memoizedProps;
const newProps = workInProgress.pendingProps;
}

// 根據(jù)不同類型的組件,進行不同的操作
switch (workInProgress.tag) {
// ...

case ClassComponent: {
const Component = workInProgress.type;
// 未處理的新 props 對象
const unresolvedProps = workInProgress.pendingProps;
const resolvedProps =
workInProgress.elementType === Component
? unresolvedProps
: resolveDefaultProps(Component, unresolvedProps);
// 更新組件
return updateClassComponent(
current,
workInProgress,
Component,
resolvedProps,
renderLanes,
);
}

// ...
}
}

current 是舊節(jié)點,workInProgress 是新節(jié)點,屬于半成品,會在執(zhí)行過程中一點點填充內(nèi)容。

beginWork 會進行深度優(yōu)先遍歷,生成的新節(jié)點 workInProcess 會 tag 屬性進入不同的 update 邏輯分支,比如常見的 updateHostRoot、updateClassComponent、updateFunctionComponent 等。

  1. 會做組件實例化,拿到新 ReactElement,然后調(diào)用 reconcileChildFibers 方法進行 新舊節(jié)點 diff,深度遞歸構(gòu)建子 fiber,形成子 fiber 樹,并把一些數(shù)據(jù)持久化掛載到 fiber 上。
  2. 在這個過程中,會給 workInProcess 打標記。具體是在 fiber.flags 上標記  Placement(插入)、Update(更新)等 flags。比如在同層級進行對比,發(fā)現(xiàn)舊節(jié)點有需要刪除的 fiber,這些 fiber 會放到新父 fiber 的 deletions 數(shù)組中,并加上 ChildDetetion 標簽。
  3. 這期間穿插調(diào)用了一些生命周期函數(shù)(比如 shouldComponentUpdate),都是是在新舊節(jié)點對比前,準確來說是調(diào)用 render 拿到 ReactElement 的時機之前。

completeUnitOfWork

performUnitOfWork 中,調(diào)用完 beginWork 后,會返回一個 next。這個 next 就是下一個要處理的 fiber,是 unitOfWork 的子 fiber。

這個 next 會賦值給 workInProgress,然后 workLoopConcurrent 的循環(huán)會 處理這個新的 workInProcess。

但當 next 為 null,就表示找不到下一個 fiber 了,深度的 “遞” 到底了,就要 調(diào)用 completeUnitOfWork,進行 “歸” 的收尾工作。

completeUnitOfWork 做的主要工作有:

  1. 根據(jù) fiber 的類型不同,進行不同的處理。對于原生組件類型(比如 div、span)的掛載階段,會用 createInstance 創(chuàng)建 一個真實 DOM,這個 DOM 下還沒有子節(jié)點,然后還會將其下所有子 fiber 對應(yīng)的真實 DOM 加到這個 DOM 下,然后賦值給 fiber.stateNode,此時這個 DOM 元素目前什么屬性都沒有。
  2. 根據(jù) props,調(diào)用 setInitialProperties 方法綁定合成事件,以及設(shè)置 DOM 屬性。

React 16 時會生成一個 effectList 來記錄需要更新的節(jié)點,防止不必要的遍歷整棵樹。但 React 17 后被移除掉了,改成從 rootFiber 開始從上往下遍歷。

結(jié)尾

調(diào)和階段,主要分為 beginWork 和 completeUnitOfWork 兩部分。

beginWork 自上而下,進行新舊節(jié)點對比,構(gòu)造子 fiber,并打上 flag(插入、更新、刪除),會執(zhí)行 render(生成新 ReactElement) 之前的生命周期函數(shù)。對應(yīng)以前 stack reconciler 架構(gòu)中遞歸的 “遞”。

completeUnitOfWork 自下而上,如果是插入,則構(gòu)建真實 DOM 節(jié)點放到 fiber.stateNode 下,接著是處理 props,將屬性添加到 DOM 上。

責任編輯:姜華 來源: 前端西瓜哥
相關(guān)推薦

2023-03-28 07:59:57

ReactReconciler

2021-11-26 08:33:51

React組件前端

2022-07-06 08:30:36

vuereactvdom

2024-03-22 07:48:51

ReactScheduler底層調(diào)度器

2016-10-26 20:49:24

ReactJavascript前端

2021-05-11 08:48:23

React Hooks前端

2022-12-20 08:22:42

CommitMuation

2022-12-23 08:34:30

HookReact

2022-05-04 10:38:58

React閉包組件

2021-06-30 07:19:36

React事件機制

2024-04-19 12:50:58

人工智能OpenAI

2022-12-07 11:21:30

Reactdiff

2023-11-16 07:43:26

Next.jsReact

2022-05-05 08:31:48

useRefuseEffecthook

2024-01-16 08:43:51

React底層機制Hook

2022-08-21 09:41:42

ReactVue3前端

2021-07-07 08:36:45

React應(yīng)用場景

2024-04-10 10:09:07

2020-04-27 09:40:13

Reacthooks前端

2023-11-29 09:00:55

ReactuseMemo
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产一区二区黑人欧美xxxx | 欧美日韩午夜精品 | 在线视频91| 国产三级国产精品 | 99re热精品视频 | 羞羞视频网站在线观看 | 999精品在线 | 国产亚洲精品精品国产亚洲综合 | 99久久久久 | 日本一区二区高清视频 | 中文字幕久久精品 | 激情免费视频 | 黄色一级大片在线免费看产 | 在线视频日韩 | 欧美视频中文字幕 | 欧美成人精品一区二区男人看 | 精品久久久久久亚洲综合网站 | 99久久久久久久久 | 国产精品久久久久久久岛一牛影视 | 国产精品一区二 | 久久亚洲一区二区三 | 久久久久精 | 国产精品亚洲片在线播放 | 操操日 | 精品乱码一区二区三四区 | 国产成人久久精品一区二区三区 | 日本又色又爽又黄的大片 | 草久久| 亚洲欧美中文字幕在线观看 | 国产成人99久久亚洲综合精品 | 精品国产青草久久久久福利 | 日韩一级免费电影 | 天天干天天爽 | 久久久久国产 | 国产精品99久久久久久www | 亚洲3级 | 久久久婷 | 久草综合在线视频 | 你懂的免费在线 | 一区二区三区四区免费在线观看 | 日本三级在线网站 |