var FunctionComponent = 0; // Function 节点
/*
renderRoot // 主要的渲染都走这个。Diff
workLoopSync
performUnitOfWork
beginWork$1 // 注意,这个方法有别名
updateClassComponent
mountClassInstance // 在此将ReactComponent初始化成Instance
*/
var ClassComponent = 1; // Class节点
var IndeterminateComponent = 2; // 在我们知道它是函数还是类之前
var HostRoot = 3; // 宿主树的根。可以嵌套在另一个节点中。
var HostPortal = 4; // 子树。可能是其他渲染器的入口点。
var HostComponent = 5; // 主节点, <div> , <span> jsx节点
var HostText = 6; // Text 节点
/*
function FnElement () {
return <div>Element</div> // 这种类型的组件,是Fragment,而不是FunctionComponent
}
*/
var Fragment = 7;
var Mode = 8;
var ContextConsumer = 9;
var ContextProvider = 10;
var ForwardRef = 11;
var Profiler = 12;
var SuspenseComponent = 13;
var MemoComponent = 14;
var SimpleMemoComponent = 15;
var LazyComponent = 16;
var IncompleteClassComponent = 17;
var DehydratedSuspenseComponent = 18;
var SuspenseListComponent = 19;
var FundamentalComponent = 20;
function FiberNode(tag, pendingProps, key, mode) {
// Instance
// tag 标记了,当前节点的类型。
this.tag = tag;
// 标记索引
this.key = key;
// 如果tag = 1 是 class节点 elementType: ƒ ParentDom(props)
// 如果tag = 5 是 host节点 elementType: "div"
// 如果tag = 3 是 root节点 elementType: null
// 如果tag = 6 是 root节点 elementType: null
this.elementType = null;
// type 与 elementType的值一样。
this.type = null;
// class 组件是 组件的实例
// host 组件是 真实dom节点
// text 组件是 null
// root 组件是 FiberRootNode
this.stateNode = null;
// Fiber
// 父节点
this.return = null;
// 子节点的首个节点
this.child = null;
// 下一个节点
this.sibling = null;
// 节点处于children位置的下标
this.index = 0;
// 组件的实例
this.ref = null;
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
// 带有记忆的State,可以理解成,计算后的最新state状态保存在此属性中,完成后,将他交给实例
// instance.state = workInProgress.memoizedState;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
// Effects
this.effectTag = NoEffect;
// nextEffect 记录了当前是修改状态还是删除状态
// nextEffect: {effectTag: 2 | 4 | 6 }
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
this.expirationTime = NoWork;
this.childExpirationTime = NoWork;
this.alternate = null;
if (enableProfilerTimer) {
// Note: The following is done to avoid a v8 performance cliff.
//
// Initializing the fields below to smis and later updating them with
// double values will cause Fibers to end up having separate shapes.
// This behavior/bug has something to do with Object.preventExtension().
// Fortunately this only impacts DEV builds.
// Unfortunately it makes React unusably slow for some applications.
// To work around this, initialize the fields below with doubles.
//
// Learn more about this here:
// https://github.com/facebook/react/issues/14365
// https://bugs.chromium.org/p/v8/issues/detail?id=8538
this.actualDuration = Number.NaN;
this.actualStartTime = Number.NaN;
this.selfBaseDuration = Number.NaN;
this.treeBaseDuration = Number.NaN;
// It's okay to replace the initial doubles with smis after initialization.
// This won't trigger the performance cliff mentioned above,
// and it simplifies other profiler code (including DevTools).
this.actualDuration = 0;
this.actualStartTime = -1;
this.selfBaseDuration = 0;
this.treeBaseDuration = 0;
}
{
this._debugID = debugCounter++;
this._debugSource = null;
this._debugOwner = null;
this._debugIsCurrentlyTiming = false;
this._debugNeedsRemount = false;
this._debugHookTypes = null;
if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
Object.preventExtensions(this);
}
}
}
根节点
function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
...
switch () {
case HostRoot:
// 返回根节点的首个节点
return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
}
...
}
case HostRoot:
return updateHostRoot(current$$1, workInProgress, renderExpirationTime);