React V17.0源码 学习笔记(一)

2020-12-11  本文已影响0人  郭仙人不是闲人

ReactDOM.render 函数调用说明

说明 这里只讨论web端初次调用关于hydrate的全部默认为false|undefinde,不做解释

ReactDOM.render(element,container,callback)

作用: 渲染挂载的开始

legacyRenderSubtreeIntoContainer

作用:根据 container 是否存在 root 区分初始化/更新,创建或获取 fiberRoot,进而启动更新

从 container 取出 _reactRootContainer 作为 react 的一个根

const root = container._reactRootContainer

检查 root 是否存在,如果存在就是 Update,如果不存在就是初始化

若 root 存在

从 root 中取出 fiberRoot

const fiberRoot = root._internalRoot

调用 updateContainer(children,fiberRoot,parentComponent,callBack)

注意:这里 callBack 会通过 getPublicRootInstance() 递归找到 fiberRoot 上第一个非 HTMlElement 结点,并将 callback 绑定在它上边。

if (typeof callback === 'function') {
  const originalCallback = callback;
  callback = function() {
    const instance = getPublicRootInstance(fiberRoot);
    originalCallback.call(instance);
  };
}

若 root 不存在

调用 legacyCreateRootFromDOMContainer(contaiber,forceHydrate) 初始化 root。
将 root 赋值给 container._reactRootContainer,取出 root 中的_internalRoot 作为 fiberRoot。

调用 updateContainer(children,fiberRoot,parentComponent,callBack)。

//注意这里调用的时候,是非批量的。因为是初始化的内部挂载,所以需要使用非批量更新
unbatchedUpdates(() => {
  updateContainer(children, fiberRoot, parentComponent, callback);
});

// updateContainer() 就到了更新流程了,这里不讨论了^-^

legacyCreateRootFromDOMContainer

作用:清空 container,创建 root

shouleHydrate = forceHydrate && isReactContainer(contaiber)?{ hydrate:true }:undefinde

调用 createLegacyRoot(container,shouleHydrate)

createLegacyRoot

引入静态变量 LegacyRoot = 0 ,作为 RootTag

调用 new ReactDOMBlockingRoot(container,LegacyRoot,options)

ReactDOMBlockingRoot

创建 RootImpl ,赋值给 this._internalRoot 也就是 fiberRoot

this._internalRoot = createRootImpl(container, tag, options);

//注意:通过 ReactDOMBlockingRoot 创建的实例会自动实现两个函数 render 和 unmount
// 渲染根结点
render(children){
    root = this.\_internalRoot;
    updateContainer(children,root,null,null)
}
// 卸载根结点
unmount(){
    const root = this._internalRoot;
    const container = root.containerInfo;
    updateContainer(null, root, null, () => {
        // 从container中移除 __reactContainer 对应的fiber
        unmarkContainerAsRoot(container);
    });
}

createRootImpl

作用:

根据 container 创建 root

const root = createContainer(container, tag, hydrate, hydrationCallbacks);

标记 container 作为 root 的 current

// 为 container 字段 添加 __reactContainer 对应的 fiber
markContainerAsRoot(root.current, container);

为 root 容器添加所有监听事件

const rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
// 绑定事件监听,特殊处理selectionchange
listenToAllSupportedEvents(rootContainerElement);
createContainer -> createFiberRoot

作用:

createFiber

作用:
生成一个 FiberNode

FiberNode.tag = tag
FiberNode.penddingProps = penddingProps
FiberNode.mode=mode
FiberNode.key = key

上一篇 下一篇

猜你喜欢

热点阅读