美文网首页
React源码解析之FiberRoot

React源码解析之FiberRoot

作者: 小进进不将就 | 来源:发表于2019-10-04 21:43 被阅读0次

    一、FiberRoot的含义与作用
    (1)FiberRoot是整个React应用的起点
    (2)FiberRoot包含应用挂载的目标节点(<div id='root'>root</div>
    (3)FiberRoot记录整个React应用 更新过程中的各种信息

    二、与RootFiber的关系

    FiberRoot.current = RootFiber
    RootFiber.stateNode = FiberRoot
    

    三、createFiberRoot()
    作用:
    初始化fiberRoot和rootFiber

    源码:

    //初始化fiberRoot和rootFiber
    export function createFiberRoot(
      containerInfo: any,
      tag: RootTag,
      hydrate: boolean,
    ): FiberRoot {
      //新建fiberRoot对象
      const root: FiberRoot = (new FiberRootNode(containerInfo, tag, hydrate): any);
    
      // Cyclic construction. This cheats the type system right now because
      // stateNode is any.
      //初始化RootFiber
      const uninitializedFiber = createHostRootFiber(tag);
      //FiberRoot和RootFiber的关系
      //FiberRoot.current = RootFiber
      root.current = uninitializedFiber;
      //RootFiber.stateNode = FiberRoot
      uninitializedFiber.stateNode = root;
    
      return root;
    }
    

    解析:
    主要干了三件事:
    (1)创建fiberRoot对象
    (2)创建rootFiber对象,请看:React源码解析之RootFiber
    (3)各自之一keyvalue赋值给对方

    四、FiberRootNode()
    作用:
    新建fiberRoot对象

    源码:

    function FiberRootNode(containerInfo, tag, hydrate) {
      this.tag = tag;
      this.current = null;
      this.containerInfo = containerInfo;
      this.pendingChildren = null;
      this.pingCache = null;
      this.finishedExpirationTime = NoWork;
      this.finishedWork = null;
      this.timeoutHandle = noTimeout;
      this.context = null;
      this.pendingContext = null;
      this.hydrate = hydrate;
      this.firstBatch = null;
      this.callbackNode = null;
      this.callbackExpirationTime = NoWork;
      this.firstPendingTime = NoWork;
      this.lastPendingTime = NoWork;
      this.pingTime = NoWork;
    
      if (enableSchedulerTracing) {
        this.interactionThreadID = unstable_getThreadID();
        this.memoizedInteractions = new Set();
        this.pendingInteractionMap = new Map();
      }
    }
    

    由于BaseFiberRootProperties中定义了fiberRoot的绝大多数属性,所以我们直接解析下BaseFiberRootProperties

    type BaseFiberRootProperties = {|
      // The type of root (legacy, batched, concurrent, etc.)
      tag: RootTag,
    
      // Any additional information from the host associated with this root.
      //root节点,也就是ReactDOM.render(<App />, document.getElementById('root'))的第二个参数
      containerInfo: any,
      // Used only by persistent updates.
      //只有在持久更新中才会用到,也就是不支持增量更新的平台会用到,react-dom不会用到
      //也就是不更新某一块地方,而是整个应用完全更新
      pendingChildren: any,
      // The currently active root fiber. This is the mutable root of the tree.
      //当前应用root节点对应的Fiber对象,即Root Fiber
      //ReactElement会有一个树结构,同时一个ReactElement对应一个Fiber对象,
      //所以Fiber也会有树结构
      //current:Fiber对象 对应的是 root 节点,即整个应用根对象
      current: Fiber,
    
      pingCache:
        | WeakMap<Thenable, Set<ExpirationTime>>
        | Map<Thenable, Set<ExpirationTime>>
        | null,
    
      //任务有三种,优先级有高低:
      //(1)没有提交的任务
      //(2)没有提交的被挂起的任务
      //(3)没有提交的可能被挂起的任务
    
      //当前更新对应的过期时间
      finishedExpirationTime: ExpirationTime,
      // A finished work-in-progress HostRoot that's ready to be committed.
      //已经完成任务的FiberRoot对象,如果你只有一个Root,那么该对象就是这个Root对应的Fiber或null
      //在commit(提交)阶段只会处理该值对应的任务
      finishedWork: Fiber | null,
      // Timeout handle returned by setTimeout. Used to cancel a pending timeout, if
      // it's superseded by a new one.
      // 在任务被挂起的时候,通过setTimeout设置的响应内容,
      // 并且清理之前挂起的任务 还没触发的timeout
      timeoutHandle: TimeoutHandle | NoTimeout,
      // Top context object, used by renderSubtreeIntoContainer
      //顶层context对象,只有主动调用renderSubtreeIntoContainer才会生效
      context: Object | null,
      pendingContext: Object | null,
      // Determines if we should attempt to hydrate on the initial mount
      //用来判断 第一次渲染 是否需要融合
      +hydrate: boolean,
      // List of top-level batches. This list indicates whether a commit should be
      // deferred. Also contains completion callbacks.
      // TODO: Lift this into the renderer
      firstBatch: Batch | null,
      // Node returned by Scheduler.scheduleCallback
      callbackNode: *,
      // Expiration of the callback associated with this root
      //跟root有关联的回调函数的时间
      callbackExpirationTime: ExpirationTime,
      // The earliest pending expiration time that exists in the tree
      //存在root中,最旧的挂起时间
      //不确定是否挂起的状态(所有任务一开始均是该状态)
      firstPendingTime: ExpirationTime,
      // The latest pending expiration time that exists in the tree
      //存在root中,最新的挂起时间
      //不确定是否挂起的状态(所有任务一开始均是该状态)
      lastPendingTime: ExpirationTime,
      // The time at which a suspended component pinged the root to render again
      //挂起的组件通知root再次渲染的时间
      //通过一个promise被reslove并且可以重新尝试的优先级
      pingTime: ExpirationTime,
    |};
    

    解析:
    熟悉它的属性及作用,并且【留个印象】就好,大部分属性在其他文章中都有用到。

    GitHub:
    https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react-reconciler/src/ReactFiberRoot.js


    (完)

    相关文章

      网友评论

          本文标题:React源码解析之FiberRoot

          本文链接:https://www.haomeiwen.com/subject/tbdojctx.html