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
            }
      }
}   
扫描二维码关注公众号,回复: 2812618 查看本文章

在dom上附加了这么一串有用的对象 

猜你喜欢

转载自www.cnblogs.com/JhoneLee/p/9493776.html