React Fiber結(jié)構(gòu)的創(chuàng)建步驟
React Fiber的創(chuàng)建
當(dāng)前React版本基于V17.0.2版本,本篇主要介紹fiber結(jié)構(gòu)的創(chuàng)建。
一、開始之前
個(gè)人理解,如有不對(duì),請(qǐng)指出。
首先需要配置好React的debugger開發(fā)環(huán)境,入口在這里:github
執(zhí)行npm run i,安裝依賴,npm start運(yùn)行環(huán)境。
二、從React.render開始
通過(guò)在項(xiàng)目入口處調(diào)用React.render,打上Debug,查看React調(diào)用棧。
const root = document.getElementById('root');
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
root
);
在React調(diào)用render之后,在傳入基礎(chǔ)的配置后,調(diào)用legacyRenderSubtreeIntoContainer。
export function render(
element: React$Element<any>,
container: Container,
callback: ?Function,
) {
// 刪除一些環(huán)境代碼
// ...
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}
在React調(diào)用render之后,在傳入基礎(chǔ)的配置后,調(diào)用legacyRenderSubtreeIntoContainer。
export function render(
element: React$Element<any>,
container: Container,
callback: ?Function,
) {
// 刪除一些環(huán)境代碼
// ...
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}
legacyRenderSubtreeIntoContainer一共做了兩件事情,一個(gè)是生成了fiberRoot,一個(gè)是調(diào)用updateContainer。

進(jìn)入legacyCreateRootFromDOMContainer函數(shù),查看如何生成fiberRoot。 在函數(shù)內(nèi)部,調(diào)用了createLegacyRoot,在這里區(qū)分了下,是否使用hydrate,如下:
return createLegacyRoot(
container,
shouldHydrate
? {
hydrate: true,
}
: undefined,
);
對(duì)于createLegacyRoot來(lái)說(shuō),是用來(lái)實(shí)例化ReactDOMLegacyRoot函數(shù)的,通過(guò)后續(xù)調(diào)用,終于進(jìn)入到root的生成,調(diào)用createRootImpl函數(shù),實(shí)例化root。
進(jìn)入createFiberRoot函數(shù),初始化FiberRootNode。
function FiberRootNode(containerInfo, tag, hydrate) {
this.tag = tag; // 類型
this.containerInfo = containerInfo; // container
this.pendingChildren = null;
this.current = null;
this.pingCache = null;
this.finishedWork = null;
this.timeoutHandle = noTimeout;
this.context = null;
this.pendingContext = null;
this.hydrate = hydrate;
this.callbackNode = null;
this.callbackPriority = NoLanePriority;
this.eventTimes = createLaneMap(NoLanes);
this.expirationTimes = createLaneMap(NoTimestamp);
this.pendingLanes = NoLanes;
this.suspendedLanes = NoLanes;
this.pingedLanes = NoLanes;
this.mutableReadLanes = NoLanes;
this.finishedLanes = NoLanes;
this.entangledLanes = NoLanes;
this.entanglements = createLaneMap(NoLanes);
// ....
}
這里的tag,有以下幾種類型。
export type RootTag = 0 | 1;
上述的結(jié)構(gòu)是fiberRootNode節(jié)點(diǎn)。
rootTag 等于0 時(shí),代表legacy渲染模式,等于1時(shí),代表Concurrent mode渲染,也就是說(shuō),傳統(tǒng)我們使用React.render進(jìn)行渲染,當(dāng)調(diào)用React.createRoot時(shí),進(jìn)入Concurrent mode渲染模式,即并行渲染。
現(xiàn)在我們一起看看fiber的結(jié)構(gòu)。
const uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root;
uninitializedFiber為創(chuàng)建的FiberNode的創(chuàng)建的實(shí)例。
const createFiber = function(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
): Fiber {
// $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
return new FiberNode(tag, pendingProps, key, mode);
};
通過(guò)基礎(chǔ)的創(chuàng)建,生成FiberNode結(jié)構(gòu),如下
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Instance
this.tag = tag;//組件類型
this.key = key;//key屬性
this.elementType = null;//元素類型,類函數(shù),顯示類,div顯示div
this.type = null;//func或者class
this.stateNode = null;//dom節(jié)點(diǎn)
// Fiber
this.return = null;//指向父節(jié)點(diǎn)
this.child = null;//指向子節(jié)點(diǎn)
this.sibling = null;//兄弟節(jié)點(diǎn)
this.index = 0;//
this.ref = null;
this.pendingProps = pendingProps;//等待中的屬性pendingProps
this.memoizedProps = null; //記憶屬性,一般存放props
this.updateQueue = null;//更新隊(duì)列
this.memoizedState = null;// 一般存放state
this.dependencies = null;
this.mode = mode;
// Effects相關(guān)
this.flags = NoFlags;
this.subtreeFlags = NoFlags;
this.deletions = null;
this.lanes = NoLanes;
this.childLanes = NoLanes;
this.alternate = null;//指向workInProgress
}

FiberNode基本顯示如上,elementType和type的基礎(chǔ)類型為function、class。
通過(guò)對(duì)比f(wàn)iberRootNode結(jié)構(gòu),和下面的代碼,生成最終的FiberNode 結(jié)構(gòu)。
render() {
const { name, count } = this.state;
return (
<div className="App">
<Button name={name} />
{
count
}
</div>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
root
);
通過(guò)最后執(zhí)行,生成fiberRoot鏈表結(jié)構(gòu)。

最后,調(diào)用unbatchedUpdates,進(jìn)行渲染。
進(jìn)入updateContainer函數(shù)。
unbatchedUpdates(() => {
// 更新container
updateContainer(children, fiberRoot, parentComponent, callback);
});
三、結(jié)束
以上就是React Fiber結(jié)構(gòu)的創(chuàng)建步驟的詳細(xì)內(nèi)容,更多關(guān)于React Fiber結(jié)構(gòu)的創(chuàng)建的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react-json-editor-ajrm解析錯(cuò)誤與解決方案
由于歷史原因,項(xiàng)目中 JSON 編輯器使用的是 react-json-editor-ajrm,近期遇到一個(gè)嚴(yán)重的展示錯(cuò)誤,傳入編輯器的數(shù)據(jù)與展示的不一致,這是產(chǎn)品和用戶不可接受的,本文給大家介紹了react-json-editor-ajrm解析錯(cuò)誤與解決方案,需要的朋友可以參考下2024-06-06
使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能
這篇文章主要介紹了使用React Native創(chuàng)建以太坊錢包,實(shí)現(xiàn)轉(zhuǎn)賬等功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
react搭建在線編輯html的站點(diǎn)通過(guò)引入grapes實(shí)現(xiàn)在線拖拉拽編輯html
Grapes插件是一種用于Web開發(fā)的開源工具,可以幫助用戶快速創(chuàng)建動(dòng)態(tài)和交互式的網(wǎng)頁(yè)元素,它還支持多語(yǔ)言和多瀏覽器,適合開發(fā)響應(yīng)式網(wǎng)頁(yè)和移動(dòng)應(yīng)用程序,這篇文章主要介紹了react搭建在線編輯html的站點(diǎn)通過(guò)引入grapes實(shí)現(xiàn)在線拖拉拽編輯html,需要的朋友可以參考下2023-08-08
react?+?vite?+?ts項(xiàng)目中優(yōu)雅使用.svg文件
這篇文章主要為大家介紹了react?+?vite?+?ts項(xiàng)目中優(yōu)雅使用.svg文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
React實(shí)現(xiàn)雙滑塊交叉滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)雙滑塊交叉滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

