• 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上附加了这么一串有用的对象 

  • 相关阅读:
    Django REST Framework之版本控制
    Django REST Framework之频率限制
    webpack4进阶配置
    高阶函数map,filter,reduce的用法
    Vue+elementui 实现复杂表头和动态增加列的二维表格
    Pika源码学习--pika和rocksdb的对接
    Pika源码学习--pika的命令执行框架
    Pika源码学习--pika的PubSub机制
    Pika源码学习--pika的通信和线程模型
    pika源码学习--开篇
  • 原文地址:https://www.cnblogs.com/JhoneLee/p/9493776.html
Copyright © 2020-2023  润新知