上一篇讲到了createFiberRoot
function createFiberRoot(containerInfo, isConcurrent, hydrate) {
// Cyclic construction. This cheats the type system right now because
// stateNode is any.
// 首先创建hostroot
var uninitializedFiber = createHostRootFiber(isConcurrent);
var root = void 0;
// 跟踪
// Trace which interactions trigger each commit.
// var enableSchedulerTracing = true;
if (enableSchedulerTracing) {
root = {
// 指向了刚才创建的HostRoot
current: uninitializedFiber,
// container信息
containerInfo: containerInfo,
pendingChildren: null,
earliestPendingTime: NoWork,
latestPendingTime: NoWork,
earliestSuspendedTime: NoWork,
latestSuspendedTime: NoWork,
latestPingedTime: NoWork,
didError: false,
// NoWork 0
pendingCommitExpirationTime: NoWork,
finishedWork: null,
timeoutHandle: noTimeout,
context: null,
pendingContext: null,
hydrate: hydrate,
nextExpirationTimeToWorkOn: NoWork,
expirationTime: NoWork,
firstBatch: null,
nextScheduledRoot: null,
// threadIDCounter初始值0
// function unstable_getThreadID() {
// return ++threadIDCounter;
// }
interactionThreadID: tracing.unstable_getThreadID(),
memoizedInteractions: new Set(),
pendingInteractionMap: new Map()
};
} else {
root = {
current: uninitializedFiber,
containerInfo: containerInfo,
pendingChildren: null,
earliestPendingTime: NoWork,
latestPendingTime: NoWork,
earliestSuspendedTime: NoWork,
latestSuspendedTime: NoWork,
latestPingedTime: NoWork,
didError: false,
pendingCommitExpirationTime: NoWork,
finishedWork: null,
timeoutHandle: noTimeout,
context: null,
pendingContext: null,
hydrate: hydrate,
nextExpirationTimeToWorkOn: NoWork,
expirationTime: NoWork,
firstBatch: null,
nextScheduledRoot: null
};
}
uninitializedFiber.stateNode = root;
// The reason for the way the Flow types are structured in this file,
// Is to avoid needing :any casts everywhere interaction tracing fields are used.
// Unfortunately that requires an :any cast for non-interaction tracing capable builds.
// $FlowFixMe Remove this :any cast and replace it with something better.
return root;
}
函数也很简单,就是形成了一个root.current = HostRoot, HostRoot.stateNode = root
#createHostRootFiber
// isConcurrent false
function createHostRootFiber(isConcurrent) {
// var NoContext = 0;
// var ConcurrentMode = 1;
// var StrictMode = 2;
// ProfileMode =3
var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
if (enableProfilerTimer && isDevToolsPresent) {
// Always collect profile timings when DevTools are present.
// This enables DevTools to start capturing timing at any point–
// Without some nodes in the tree having empty base times.
mode |= ProfileMode;
}
// HostRoot = 3
// mode = 4
return createFiber(HostRoot, null, null, mode);
}
这里很简单,就是直接到了createFiber
createFiber
// This is a constructor function, rather than a POJO constructor, still
// please ensure we do the following:
// 1) Nobody should add any instance methods on this. Instance methods can be
// more difficult to predict when they get optimized and they are almost
// never inlined properly in static compilers.
// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
// always know when it is a fiber.
// 3) We might want to experiment with using numeric keys since they are easier
// to optimize in a non-JIT environment.
// 4) We can easily go from a constructor to a createFiber object literal if that
// is faster.
// 5) It should be easy to port this to a C struct and keep a C implementation
// compatible.
var createFiber = function (tag, pendingProps, key, mode) {
// $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
return new FiberNode(tag, pendingProps, key, mode);
};
也很简单,就是一个返回FiberNode对象。 #FiberNode
function FiberNode(tag, pendingProps, key, mode) {
// Instance
this.tag = tag;
this.key = key;
this.elementType = null;
this.type = null;
this.stateNode = null;
// Fiber
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0;
this.ref = null;
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.firstContextDependency = null;
this.mode = mode;
// Effects
this.effectTag = NoEffect;
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
this.expirationTime = NoWork;
this.childExpirationTime = NoWork;
this.alternate = null;
if (enableProfilerTimer) {
this.actualDuration = 0;
this.actualStartTime = -1;
this.selfBaseDuration = 0;
this.treeBaseDuration = 0;
}
{
this._debugID = debugCounter++;
this._debugSource = null;
this._debugOwner = null;
this._debugIsCurrentlyTiming = false;
if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
Object.preventExtensions(this);
}
}
}
就是一个对象,有各种各种的属性。 可以看下最后创建的HostRoot对象,如下图所示:

function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
// TODO: Ensure all entry points contain this check
!isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
{
topLevelUpdateWarnings(container);
}
// TODO: Without `any` type, Flow says "Property cannot be accessed on any
// member of intersection type." Whyyyyyy.
var root = container._reactRootContainer;
if (!root) {
// Initial mount
// root._internalRoot 就是在刚才创建的root对象,
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
// callback null
if (typeof callback === 'function') {
var originalCallback = callback;
callback = function () {
var instance = getPublicRootInstance(root._internalRoot);
originalCallback.call(instance);
};
}
// Initial mount should not be batched.
// 初次渲染的时候,
unbatchedUpdates(function () {
if (parentComponent != null) {
root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
} else {
// container完成之后,渲染子组件
root.render(children, callback);
}
});
} else {
if (typeof callback === 'function') {
var _originalCallback = callback;
callback = function () {
var instance = getPublicRootInstance(root._internalRoot);
_originalCallback.call(instance);
};
}
// Update
if (parentComponent != null) {
root.legacy_renderSubtreeIntoContainer(parentComponent, children, callback);
} else {
root.render(children, callback);
}
}
return getPublicRootInstance(root._internalRoot);
}
然后就会执行
ReactRoot.prototype.render = function (children, callback) {
// 就是创建的root对象
var root = this._internalRoot;
// 创建reactwork
var work = new ReactWork();
callback = callback === undefined ? null : callback;
{
warnOnInvalidCallback(callback, 'render');
}
if (callback !== null) {
work.then(callback);
}
// 更新container
updateContainer(children, root, null, work._onCommit);
return work;
};