React 16 源碼瞎幾把解讀 【三 點 二】 react中的fiberRoot


〇、先來看看常用的常量

NoWork = 0

noTimeout = undefined

HostRoot = 3

NoContext = 0b000;

AsyncMode = 0b001;

StrictMode = 0b010;

ProfileMode = 0b100;

NoEffect = /*              */ 0b00000000000

enableProfilerTimer = __PROFILE__

__PROFILE__: true

isDevToolsPresent =  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined'

一、制造root._internalRoot 的 createFiberRoot 方法 

 1 export function createFiberRoot(
 2   containerInfo: any,  // id=app 的 dom
 3   isAsync: boolean, // false
 4   hydrate: boolean, // false
 5 ): FiberRoot {
 6   const uninitializedFiber = createHostRootFiber(isAsync);
 7   const root = {
 8     current: uninitializedFiber, // 添加fiber 屬性 一直用它
 9     containerInfo: containerInfo, // dom app
10     pendingChildren: null,
11 
12     earliestPendingTime: NoWork,
13     latestPendingTime: NoWork,
14     earliestSuspendedTime: NoWork,
15     latestSuspendedTime: NoWork,
16     latestPingedTime: NoWork,
17 
18     didError: false,
19 
20     pendingCommitExpirationTime: NoWork,
21     finishedWork: null,
22     timeoutHandle: noTimeout,
23     context: null,
24     pendingContext: null,
25     hydrate, //false
26     nextExpirationTimeToWorkOn: NoWork,
27     expirationTime: NoWork,
28     firstBatch: null,
29     nextScheduledRoot: null,
30   };
31   uninitializedFiber.stateNode = root;
32   return root;
33 }
View Code

通過上面的代碼得知,造出來的root._internalRoot 是一個包含若干屬性的對象,其中最重要的是一個名叫 current的屬性,這個current屬性在上一集我們說到虛擬dom渲染過程的時候被當做第一參數 傳入了 渲染核心函數 enqueueUpdate中。

這個current屬性是個核心

二、 制造current屬性的createHostRootFiber(isAsync)方法

 1 export function createHostRootFiber(
 2   isAsync: boolean // false
 3 ): Fiber {
 4   // export type TypeOfMode = number;
 5   // export const NoContext = 0b000;
 6   // export const AsyncMode = 0b001;
 7   // export const StrictMode = 0b010;
 8   // export const ProfileMode = 0b100;
 9   let mode = isAsync ? AsyncMode | StrictMode : NoContext; // 0b000
10   // __PROFILE__: true,
11   // export const enableProfilerTimer = __PROFILE__;
12   // export const isDevToolsPresent =  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
13   if (enableProfilerTimer && isDevToolsPresent) {
14     // Always collect profile timings when DevTools are present.
15     // This enables DevTools to start capturing timing at any point–
16     // Without some nodes in the tree having empty base times.
17     mode |= ProfileMode; // 0b100
18   }
19   // export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
20   return createFiber(HostRoot, null, null, mode);
21 }
View Code

這些代碼無非是通過入參 isAsync 確定了mode的值,用來決定創造出的current是個具有根節點屬性的東西

 

三、通用方法createFiber -> new FiberNode(...)

createFiber方法只是簡單的返回了 new FiberNode(...),我們只需要看FiberNode是個啥

 1 function FiberNode(
 2   tag: TypeOfWork,
 3   pendingProps: mixed,
 4   key: null | string,
 5   mode: TypeOfMode,
 6 ) {
 7   // Instance
 8   this.tag = tag;
 9   this.key = key;
10   this.type = null;
11   this.stateNode = null;
12 
13   // Fiber
14   this.return = null;
15   this.child = null;
16   this.sibling = null;
17   this.index = 0;
18 
19   this.ref = null;
20 
21   this.pendingProps = pendingProps;
22   this.memoizedProps = null;
23   this.updateQueue = null;
24   this.memoizedState = null;
25   this.firstContextDependency = null;
26 
27   this.mode = mode;
28 
29   // Effects
30   // export const NoEffect = /*              */ 0b00000000000;
31   this.effectTag = NoEffect;
32   this.nextEffect = null;
33 
34   this.firstEffect = null;
35   this.lastEffect = null;
36 
37   this.expirationTime = NoWork; // 0
38   this.childExpirationTime = NoWork; // 0
39 
40   this.alternate = null;
41 
42   if (enableProfilerTimer) {
43     this.actualDuration = 0;
44     this.actualStartTime = 0;
45     this.selfBaseDuration = 0;
46     this.treeBaseDuration = 0;
47   }
48 }
View Code

附加了一堆將來fiber架構需要用到的屬性,具體這些屬性是干啥用的,咱們以后再分析

 

不知道大家還記不記得這個root從我們調用reactDOM.render 傳入那個container 往上附加了多少有用的東西,現在來回顧一下:

container 就是咱們傳入的那個真實dom

 

container = {
     _reactRootContainer :{ // legacyCreateRootFromDOMContainer
            _internalRoot: { // DOMRenderer.createContainer
                     current:{}  // new FiberNode
            }
      }
}   

 

在dom上附加了這么一串有用的對象 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM