摘要:一的含義和作用每一個對應(yīng)一個對象記錄節(jié)點的各種狀態(tài)比如中的和的狀態(tài)就是記錄在對象上的。只有當(dāng)對象更新后,才會更新到上的和上上的和是根據(jù)對象的更新的。
一、Fiber的含義和作用
(1)每一個ReactElement對應(yīng)一個Fiber對象
(2)記錄節(jié)點的各種狀態(tài)
比如ClassComponent中的state和props的狀態(tài)就是記錄在Fiber對象上的。
只有當(dāng)Fiber對象更新后,才會更新到ClassComponent上的this.state和this.props上
this上的state和props是根據(jù)Fiber對象的state、props更新的。
這實際上也方便了ReactHooks,因為hooks是為FunctionalComponent服務(wù)的。雖然FunctionalComponent沒有this,但Fiber上有,是可以拿到state和props的
(3)串聯(lián)整個應(yīng)用形成樹結(jié)構(gòu)
每個ReactElement通過props.children與其他ReactElement連結(jié)起來
說明:
① ReactElement只會把子節(jié)點(props.children)的第一個子節(jié)點當(dāng)做child節(jié)點,其余的子節(jié)點(也就是第一個子節(jié)點的兄弟節(jié)點)都是從第一個子節(jié)點開始,依次單向連接至后一個兄弟節(jié)點
② 每個子節(jié)點都會指向父節(jié)點(紅箭頭),也就是Fiber對象的return屬性
export type Fiber = {| //指向該對象在Fiber節(jié)點樹中的`parent`,用來在處理完該節(jié)點后返回 //即流程圖上的紅線 return: Fiber | null, }
串聯(lián)過程:
① 任一 葉子 節(jié)點A,如果有兄弟節(jié)點,則去單向向后遍歷兄弟節(jié)點,最后return到父節(jié)點
② 父節(jié)點的child節(jié)點不是剛剛的子節(jié)點A的話,則從child節(jié)點遍歷到A前的節(jié)點,并再次return到父節(jié)點
③ 該父節(jié)點執(zhí)行 ①、②
根據(jù)圖1舉例:
比如從左下角的input節(jié)點開始,它沒有兄弟節(jié)點,則return到父組件Input(因為父節(jié)點有且只有一個,所以必定return到父節(jié)點)
Input有兄弟節(jié)點List,List又有child節(jié)點,則從child節(jié)點往后單向遍歷兄弟節(jié)點,最后return到List
List又return到div,div的child節(jié)點已被遍歷,則return到App節(jié)點,App,App又return到所有Fiber對象的根對象RootFiber對象
這樣,就將整個應(yīng)用遍歷完了。
二、Fiber對象
源碼:
// A Fiber is work on a Component that needs to be done or was done. There can // be more than one per component. //Fiber對應(yīng)一個即將update或已經(jīng)update的組件, // 一個組件可以有一個或多個Fiber export type Fiber = {| // These first fields are conceptually members of an Instance. This used to // be split into a separate type and intersected with the other Fiber fields, // but until Flow fixes its intersection bugs, we"ve merged them into a // single type. // An Instance is shared between all versions of a component. We can easily // break this out into a separate object to avoid copying so much to the // alternate versions of the tree. We put this on a single object for now to // minimize the number of objects created during the initial render. // Tag identifying the type of fiber. //標(biāo)記不同的組件類型 //有原生的DOM節(jié)點,有React自己的節(jié)點 tag: WorkTag, // Unique identifier of this child. //ReactElement里面的key key: null | string, // The value of element.type which is used to preserve the identity during // reconciliation of this child. //ReactElement.type,也就是我們調(diào)用createElement的第一個參數(shù) elementType: any, // The resolved function/class/ associated with this fiber. //異步組件resolve之后返回的內(nèi)容,一般是function或class //比如懶加載 type: any, // The local state associated with this fiber. //當(dāng)前Fiber的狀態(tài)(比如瀏覽器環(huán)境就是DOM節(jié)點) //不同類型的實例都會記錄在stateNode上 //比如DOM組件對應(yīng)DOM節(jié)點實例 //ClassComponent對應(yīng)Class實例 //FunctionComponent沒有實例,所以stateNode值為null //state更新了或props更新了均會更新到stateNode上 stateNode: any, // Conceptual aliases // parent : Instance -> return The parent happens to be the same as the // return fiber since we"ve merged the fiber and instance. // Remaining fields belong to Fiber // The Fiber to return to after finishing processing this one. // This is effectively the parent, but there can be multiple parents (two) // so this is only the parent of the thing we"re currently processing. // It is conceptually the same as the return address of a stack frame. //指向該對象在Fiber節(jié)點樹中的`parent`,用來在處理完該節(jié)點后返回 //即流程圖上的紅線 return: Fiber | null, // Singly Linked List Tree Structure. //單鏈表樹結(jié)構(gòu) //指向自己的第一個子節(jié)點 child: Fiber | null, //指向自己的兄弟結(jié)構(gòu) //兄弟節(jié)點的return指向同一個父節(jié)點 sibling: Fiber | null, index: number, // The ref last used to attach this node. // I"ll avoid adding an owner field for prod and model that as functions. //ref屬性 ref: null | (((handle: mixed) => void) & {_stringRef: ?string}) | RefObject, // Input is the data coming into process this fiber. Arguments. Props. //新的變動帶來的新的props,即nextProps pendingProps: any, // This type will be more specific once we overload the tag. //上一次渲染完成后的props,即 props memoizedProps: any, // The props used to create the output. // A queue of state updates and callbacks. //該Fiber對應(yīng)的組件,所產(chǎn)生的update,都會放在該隊列中 updateQueue: UpdateQueue| null, // The state used to create the output //上次渲染的state,即 state //新的state由updateQueue計算得出,并覆蓋memoizedState memoizedState: any, // Dependencies (contexts, events) for this fiber, if it has any //一個列表,存在該Fiber依賴的contexts,events dependencies: Dependencies | null, // Bitfield that describes properties about the fiber and its subtree. E.g. // the ConcurrentMode flag indicates whether the subtree should be async-by- // default. When a fiber is created, it inherits the mode of its // parent. Additional flags can be set at creation time, but after that the // value should remain unchanged throughout the fiber"s lifetime, particularly // before its child fibers are created. //mode有conCurrentMode和strictMode //用來描述當(dāng)前Fiber和其他子樹的Bitfield //共存的模式表示這個子樹是否默認(rèn)是 異步渲染的 //Fiber剛被創(chuàng)建時,會繼承父Fiber //其他標(biāo)識也可以在創(chuàng)建的時候被設(shè)置,但是創(chuàng)建之后不該被修改,特別是它的子Fiber創(chuàng)建之前 mode: TypeOfMode, //以下屬性是副作用 //副作用是 標(biāo)記組件哪些需要更新的工具、標(biāo)記組件需要執(zhí)行哪些生命周期的工具 // Effect effectTag: SideEffectTag, // Singly linked list fast path to the next fiber with side-effects. nextEffect: Fiber | null, // The first and last fiber with side-effect within this subtree. This allows // us to reuse a slice of the linked list when we reuse the work done within // this fiber. firstEffect: Fiber | null, lastEffect: Fiber | null, // Represents a time in the future by which this work should be completed. // Does not include work found in its subtree. //代表任務(wù)在未來的哪個時間點 應(yīng)該被完成 //不包括該Fiber的子樹產(chǎn)生的任務(wù) expirationTime: ExpirationTime, // This is used to quickly determine if a subtree has no pending changes. //快速確定子樹中是否有 update //如果子節(jié)點有update的話,就記錄應(yīng)該更新的時間 childExpirationTime: ExpirationTime, // This is a pooled version of a Fiber. Every fiber that gets updated will // eventually have a pair. There are cases when we can clean up pairs to save // memory if we need to. // 在FIber樹更新的過程中,每個Fiber都有與其對應(yīng)的Fiber //我們稱之為 current <==> workInProgress //在渲染完成后,會交換位置 //doubleBuffer Fiber在更新后,不用再重新創(chuàng)建對象, // 而是復(fù)制自身,并且兩者相互復(fù)用,用來提高性能 alternate: Fiber | null, // Time spent rendering this Fiber and its descendants for the current update. // This tells us how well the tree makes use of sCU for memoization. // It is reset to 0 each time we render and only updated when we don"t bailout. // This field is only set when the enableProfilerTimer flag is enabled. actualDuration?: number, // If the Fiber is currently active in the "render" phase, // This marks the time at which the work began. // This field is only set when the enableProfilerTimer flag is enabled. actualStartTime?: number, // Duration of the most recent render time for this Fiber. // This value is not updated when we bailout for memoization purposes. // This field is only set when the enableProfilerTimer flag is enabled. selfBaseDuration?: number, // Sum of base times for all descedents of this Fiber. // This value bubbles up during the "complete" phase. // This field is only set when the enableProfilerTimer flag is enabled. treeBaseDuration?: number, // Conceptual aliases // workInProgress : Fiber -> alternate The alternate used for reuse happens // to be the same as work in progress. // __DEV__ only _debugID?: number, _debugSource?: Source | null, _debugOwner?: Fiber | null, _debugIsCurrentlyTiming?: boolean, _debugNeedsRemount?: boolean, // Used to verify that the order of hooks does not change between renders. _debugHookTypes?: Array | null, |};
解析:
熟悉Fiber的含義和屬性含義就可以了,之后講React更新的時候,還會提到它。
GitHub:
https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react-reconciler/src/ReactFiber.js
三、總結(jié)
(1)Fiber的三個作用
(2)單向遍歷
(3)props.children連接
(4)子指父
(5)doubleBuffer
(完)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/110000.html
摘要:查看創(chuàng)建核心函數(shù)源碼行調(diào)用函數(shù)創(chuàng)建是相關(guān),不用管源碼行這個指的是調(diào)用創(chuàng)建,下面我們將會說到對象源碼行源碼行函數(shù)中,首先創(chuàng)建了一個,然后又創(chuàng)建了一個,它們兩者還是相互引用。 感謝 yck: 剖析 React 源碼解析,本篇文章是在讀完他的文章的基礎(chǔ)上,將他的文章進(jìn)行拆解和加工,加入我自己的一下理解和例子,便于大家理解。覺得yck寫的真的很棒 。React 版本為 16.8.6,關(guān)于源碼的...
摘要:一更新的方式有三種渲染接下來,我們就來看下源碼二作用在提供的里渲染一個元素,并返回對該組件的引用常見的用法是這個官網(wǎng)網(wǎng)址源碼服務(wù)端使用方法渲染節(jié)點是讓服務(wù)端盡可能復(fù)用節(jié)點,提高性能元素容器應(yīng)用渲染結(jié)束后,調(diào)用的函數(shù)錯誤抓取方法本質(zhì)是返回 showImg(https://segmentfault.com/img/remote/1460000020064414?w=1240&h=641);...
摘要:是整個應(yīng)用的起點,包含應(yīng)用掛載的目標(biāo)節(jié)點,記錄整個應(yīng)用更新過程的各種信息是一個對象是當(dāng)前應(yīng)用對應(yīng)的對象,即。每個節(jié)點會對應(yīng)一個對象,記錄節(jié)點的各種狀態(tài),比如,,這些狀態(tài)更新完成后會被更新,是所對應(yīng)節(jié)點的實際的實例,比如對應(yīng)一個就是一個。 ReactDom.render做了什么 首先react代碼分為react和react-dom兩個包,react中代碼量特別的少,基本就是API的定義,...
摘要:大家可以看到是構(gòu)造函數(shù)構(gòu)造出來的,并且內(nèi)部有一個對象,這個對象是本文接下來要重點介紹的對象,接下來我們就來一窺究竟吧。在構(gòu)造函數(shù)內(nèi)部就進(jìn)行了一步操作,那就是創(chuàng)建了一個對象,并掛載到了上。下一篇文章還是流程相關(guān)的內(nèi)容。這是我的剖析 React 源碼的第二篇文章,如果你沒有閱讀過之前的文章,請務(wù)必先閱讀一下 第一篇文章 中提到的一些注意事項,能幫助你更好地閱讀源碼。 文章相關(guān)資料 React ...
摘要:因為版本將真正廢棄這三生命周期到目前為止,的渲染機制遵循同步渲染首次渲染,更新時更新時卸載時期間每個周期函數(shù)各司其職,輸入輸出都是可預(yù)測,一路下來很順暢。通過進(jìn)一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個生命周期函數(shù)都發(fā)生在虛擬的構(gòu)建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時間準(zhǔn)備前端招聘事項...
閱讀 2916·2023-04-25 19:08
閱讀 1416·2021-11-16 11:45
閱讀 1964·2021-10-13 09:40
閱讀 4127·2021-09-30 09:47
閱讀 2415·2019-08-30 15:44
閱讀 2261·2019-08-30 13:03
閱讀 1386·2019-08-30 12:56
閱讀 1890·2019-08-26 14:04