Match-id-e5f256f484c40e75367de107774839a066267d89
This commit is contained in:
commit
4795d103bd
|
@ -71,7 +71,7 @@ export function handleRenderThrowError(
|
||||||
// vNode抛出了异常,标记Interrupted中断
|
// vNode抛出了异常,标记Interrupted中断
|
||||||
FlagUtils.markInterrupted(sourceVNode);
|
FlagUtils.markInterrupted(sourceVNode);
|
||||||
// dirtyNodes 不再有效
|
// dirtyNodes 不再有效
|
||||||
sourceVNode.dirtyNodes = [];
|
sourceVNode.dirtyNodes = null;
|
||||||
|
|
||||||
// error是个promise
|
// error是个promise
|
||||||
if (error !== null && typeof error === 'object' && typeof error.then === 'function') {
|
if (error !== null && typeof error === 'object' && typeof error.then === 'function') {
|
||||||
|
|
|
@ -57,10 +57,23 @@ function resetProcessingVariables(startUpdateVNode: VNode) {
|
||||||
// 收集有变化的节点,在submit阶段继续处理
|
// 收集有变化的节点,在submit阶段继续处理
|
||||||
function collectDirtyNodes(vNode: VNode, parent: VNode): void {
|
function collectDirtyNodes(vNode: VNode, parent: VNode): void {
|
||||||
// 将子树和此vNode的所有效果附加到父树的效果列表中,子项的完成顺序会影响副作用顺序。
|
// 将子树和此vNode的所有效果附加到父树的效果列表中,子项的完成顺序会影响副作用顺序。
|
||||||
parent.dirtyNodes.push(...vNode.dirtyNodes);
|
const dirtyNodes = vNode.dirtyNodes;
|
||||||
|
if (dirtyNodes !== null && dirtyNodes.length) {
|
||||||
|
if (parent.dirtyNodes === null) {
|
||||||
|
parent.dirtyNodes = [...vNode.dirtyNodes];
|
||||||
|
} else {
|
||||||
|
parent.dirtyNodes.push(...vNode.dirtyNodes);
|
||||||
|
}
|
||||||
|
dirtyNodes.length = 0;
|
||||||
|
vNode.dirtyNodes = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (FlagUtils.hasAnyFlag(vNode)) {
|
if (FlagUtils.hasAnyFlag(vNode)) {
|
||||||
parent.dirtyNodes.push(vNode);
|
if (parent.dirtyNodes === null) {
|
||||||
|
parent.dirtyNodes = [vNode];
|
||||||
|
} else {
|
||||||
|
parent.dirtyNodes.push(vNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,11 @@ function calcState(
|
||||||
function collectCallbacks(vNode: VNode, update: Update) {
|
function collectCallbacks(vNode: VNode, update: Update) {
|
||||||
if (update.callback !== null) {
|
if (update.callback !== null) {
|
||||||
FlagUtils.markCallback(vNode);
|
FlagUtils.markCallback(vNode);
|
||||||
vNode.stateCallbacks.push(update.callback);
|
if (vNode.stateCallbacks === null) {
|
||||||
|
vNode.stateCallbacks = [update.callback];
|
||||||
|
} else {
|
||||||
|
vNode.stateCallbacks.push(update.callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,19 @@ import {throwNotInFuncError} from '../../hooks/BaseHook';
|
||||||
|
|
||||||
// 重置依赖
|
// 重置依赖
|
||||||
export function resetDepContexts(vNode: VNode): void {
|
export function resetDepContexts(vNode: VNode): void {
|
||||||
vNode.depContexts = [];
|
vNode.depContexts = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收集依赖
|
// 收集依赖
|
||||||
function collectDeps<T>(vNode: VNode, context: ContextType<T>) {
|
function collectDeps<T>(vNode: VNode, context: ContextType<T>) {
|
||||||
const depContexts = vNode.depContexts;
|
const depContexts = vNode.depContexts;
|
||||||
if (!depContexts.length) {
|
if (depContexts === null) {
|
||||||
|
vNode.depContexts = [context];
|
||||||
|
} else {
|
||||||
vNode.isDepContextChange = false;
|
vNode.isDepContextChange = false;
|
||||||
}
|
if (!depContexts.includes(context)) {
|
||||||
if (!depContexts.includes(context)) {
|
depContexts.push(context);
|
||||||
depContexts.push(context);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@ function isNoKeyFragment(child: any) {
|
||||||
// 清除单个节点
|
// 清除单个节点
|
||||||
function deleteVNode(parentNode: VNode, delVNode: VNode): void {
|
function deleteVNode(parentNode: VNode, delVNode: VNode): void {
|
||||||
FlagUtils.setDeletion(delVNode);
|
FlagUtils.setDeletion(delVNode);
|
||||||
|
if (parentNode.dirtyNodes === null) {
|
||||||
|
parentNode.dirtyNodes = [delVNode];
|
||||||
|
return;
|
||||||
|
}
|
||||||
parentNode.dirtyNodes.push(delVNode);
|
parentNode.dirtyNodes.push(delVNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ function handleContextChange(processing: VNode, context: ContextType<any>): void
|
||||||
// 从vNode开始遍历
|
// 从vNode开始遍历
|
||||||
travelVNodeTree(vNode, node => {
|
travelVNodeTree(vNode, node => {
|
||||||
const depContexts = node.depContexts;
|
const depContexts = node.depContexts;
|
||||||
if (depContexts.length) {
|
if (depContexts && depContexts.length) {
|
||||||
isMatch = matchDependencies(depContexts, context, node) ?? isMatch;
|
isMatch = matchDependencies(depContexts, context, node) ?? isMatch;
|
||||||
}
|
}
|
||||||
}, node =>
|
}, node =>
|
||||||
|
|
|
@ -27,23 +27,24 @@ export function isSchedulingEffects() {
|
||||||
|
|
||||||
export function callUseEffects(vNode: VNode) {
|
export function callUseEffects(vNode: VNode) {
|
||||||
const effectList: EffectList = vNode.effectList;
|
const effectList: EffectList = vNode.effectList;
|
||||||
|
if (effectList !== null) {
|
||||||
effectList.forEach(effect => {
|
effectList.forEach(effect => {
|
||||||
const {effectConstant} = effect;
|
const {effectConstant} = effect;
|
||||||
if (
|
if (
|
||||||
(effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect &&
|
(effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect &&
|
||||||
(effectConstant & EffectConstant.DepsChange) !== EffectConstant.NoEffect
|
(effectConstant & EffectConstant.DepsChange) !== EffectConstant.NoEffect
|
||||||
) {
|
) {
|
||||||
hookEffects.push(effect);
|
hookEffects.push(effect);
|
||||||
hookRemoveEffects.push(effect);
|
hookRemoveEffects.push(effect);
|
||||||
|
|
||||||
// 异步调用
|
// 异步调用
|
||||||
if (!isScheduling) {
|
if (!isScheduling) {
|
||||||
isScheduling = true;
|
isScheduling = true;
|
||||||
runAsync(runAsyncEffects);
|
runAsync(runAsyncEffects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runAsyncEffects() {
|
export function runAsyncEffects() {
|
||||||
|
@ -85,23 +86,24 @@ export function runAsyncEffects() {
|
||||||
// 在销毁vNode的时候调用remove
|
// 在销毁vNode的时候调用remove
|
||||||
export function callEffectRemove(vNode: VNode) {
|
export function callEffectRemove(vNode: VNode) {
|
||||||
const effectList: EffectList = vNode.effectList;
|
const effectList: EffectList = vNode.effectList;
|
||||||
|
if (effectList !== null) {
|
||||||
effectList.forEach(effect => {
|
effectList.forEach(effect => {
|
||||||
const {removeEffect, effectConstant} = effect;
|
const {removeEffect, effectConstant} = effect;
|
||||||
|
|
||||||
if (removeEffect !== undefined) {
|
if (removeEffect !== undefined) {
|
||||||
if ((effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect) { // 如果是useEffect,就异步调用
|
if ((effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect) { // 如果是useEffect,就异步调用
|
||||||
hookRemoveEffects.push(effect);
|
hookRemoveEffects.push(effect);
|
||||||
|
|
||||||
if (!isScheduling) {
|
if (!isScheduling) {
|
||||||
isScheduling = true;
|
isScheduling = true;
|
||||||
runAsync(runAsyncEffects);
|
runAsync(runAsyncEffects);
|
||||||
|
}
|
||||||
|
} else { // 是useLayoutEffect,直接执行
|
||||||
|
removeEffect();
|
||||||
}
|
}
|
||||||
} else { // 是useLayoutEffect,直接执行
|
|
||||||
removeEffect();
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同步执行UseLayoutEffect的remove
|
// 同步执行UseLayoutEffect的remove
|
||||||
|
@ -109,26 +111,29 @@ export function callUseLayoutEffectRemove(vNode: VNode) {
|
||||||
const effectList: EffectList = vNode.effectList;
|
const effectList: EffectList = vNode.effectList;
|
||||||
|
|
||||||
const layoutLabel = EffectConstant.LayoutEffect | EffectConstant.DepsChange;
|
const layoutLabel = EffectConstant.LayoutEffect | EffectConstant.DepsChange;
|
||||||
effectList.forEach(effect => {
|
if (effectList !== null) {
|
||||||
if ((effect.effectConstant & layoutLabel) === layoutLabel) {
|
effectList.forEach(effect => {
|
||||||
const remove = effect.removeEffect;
|
if ((effect.effectConstant & layoutLabel) === layoutLabel) {
|
||||||
effect.removeEffect = undefined;
|
const remove = effect.removeEffect;
|
||||||
if (typeof remove === 'function') {
|
effect.removeEffect = undefined;
|
||||||
remove();
|
if (typeof remove === 'function') {
|
||||||
|
remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同步执行UseLayoutEffect
|
// 同步执行UseLayoutEffect
|
||||||
export function callUseLayoutEffectCreate(vNode: VNode) {
|
export function callUseLayoutEffectCreate(vNode: VNode) {
|
||||||
const effectList: EffectList = vNode.effectList;
|
const effectList: EffectList = vNode.effectList;
|
||||||
|
if (effectList !== null) {
|
||||||
const layoutLabel = EffectConstant.LayoutEffect | EffectConstant.DepsChange;
|
const layoutLabel = EffectConstant.LayoutEffect | EffectConstant.DepsChange;
|
||||||
effectList.forEach(effect => {
|
effectList.forEach(effect => {
|
||||||
if ((effect.effectConstant & layoutLabel) === layoutLabel) {
|
if ((effect.effectConstant & layoutLabel) === layoutLabel) {
|
||||||
const create = effect.effect;
|
const create = effect.effect;
|
||||||
effect.removeEffect = create();
|
effect.removeEffect = create();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,14 @@ function callBeforeSubmitLifeCycles(
|
||||||
// 调用vNode.stateCallbacks
|
// 调用vNode.stateCallbacks
|
||||||
function callStateCallback(vNode: VNode, obj: any): void {
|
function callStateCallback(vNode: VNode, obj: any): void {
|
||||||
const stateCallbacks = vNode.stateCallbacks;
|
const stateCallbacks = vNode.stateCallbacks;
|
||||||
vNode.stateCallbacks = [];
|
vNode.stateCallbacks = null;
|
||||||
|
if (stateCallbacks !== null) {
|
||||||
stateCallbacks.forEach(callback => {
|
stateCallbacks.forEach(callback => {
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
callback.call(obj);
|
callback.call(obj);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用界面变化后的生命周期
|
// 调用界面变化后的生命周期
|
||||||
|
|
|
@ -40,11 +40,15 @@ export function submitToRender(treeRoot) {
|
||||||
|
|
||||||
if (FlagUtils.hasAnyFlag(startVNode)) {
|
if (FlagUtils.hasAnyFlag(startVNode)) {
|
||||||
// 把自己加上
|
// 把自己加上
|
||||||
startVNode.dirtyNodes.push(startVNode);
|
if (startVNode.dirtyNodes === null) {
|
||||||
|
startVNode.dirtyNodes = [startVNode];
|
||||||
|
} else {
|
||||||
|
startVNode.dirtyNodes.push(startVNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dirtyNodes = startVNode.dirtyNodes;
|
const dirtyNodes = startVNode.dirtyNodes;
|
||||||
if (dirtyNodes.length) {
|
if (dirtyNodes !== null && dirtyNodes.length) {
|
||||||
const preMode = copyExecuteMode();
|
const preMode = copyExecuteMode();
|
||||||
changeMode(InRender, true);
|
changeMode(InRender, true);
|
||||||
|
|
||||||
|
@ -60,7 +64,9 @@ export function submitToRender(treeRoot) {
|
||||||
// after submit阶段
|
// after submit阶段
|
||||||
afterSubmit(dirtyNodes);
|
afterSubmit(dirtyNodes);
|
||||||
|
|
||||||
setExecuteMode(preMode)
|
setExecuteMode(preMode);
|
||||||
|
dirtyNodes.length = 0;
|
||||||
|
startVNode.dirtyNodes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSchedulingEffects()) {
|
if (isSchedulingEffects()) {
|
||||||
|
|
|
@ -25,17 +25,17 @@ export class VNode {
|
||||||
|
|
||||||
suspensePromises: any = null; // suspense组件的promise列表
|
suspensePromises: any = null; // suspense组件的promise列表
|
||||||
changeList: any = null; // DOM的变更列表
|
changeList: any = null; // DOM的变更列表
|
||||||
effectList: any[] = []; // useEffect 的更新数组
|
effectList: any[] | null = null; // useEffect 的更新数组
|
||||||
updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组
|
updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组
|
||||||
stateCallbacks: any[] = []; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组
|
stateCallbacks: any[] | null = null; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组
|
||||||
isForceUpdate: boolean = false; // 是否使用强制更新
|
isForceUpdate: boolean = false; // 是否使用强制更新
|
||||||
|
|
||||||
state: any = null; // ClassComponent和TreeRoot的状态
|
state: any = null; // ClassComponent和TreeRoot的状态
|
||||||
hooks: Array<Hook<any, any>> = []; // 保存hook
|
hooks: Array<Hook<any, any>> | null = null; // 保存hook
|
||||||
suspenseChildStatus: string = ''; // Suspense的Children是否显示
|
suspenseChildStatus: string = ''; // Suspense的Children是否显示
|
||||||
depContexts: Array<ContextType<any>> = []; // FunctionComponent和ClassComponent对context的依赖列表
|
depContexts: Array<ContextType<any>> | null = null; // FunctionComponent和ClassComponent对context的依赖列表
|
||||||
isDepContextChange: boolean = false; // context是否变更
|
isDepContextChange: boolean = false; // context是否变更
|
||||||
dirtyNodes: Array<VNode> = []; // 需要改动的节点数组
|
dirtyNodes: Array<VNode> | null = null; // 需要改动的节点数组
|
||||||
shouldUpdate: boolean = false;
|
shouldUpdate: boolean = false;
|
||||||
childShouldUpdate: boolean = false;
|
childShouldUpdate: boolean = false;
|
||||||
outerDom: any;
|
outerDom: any;
|
||||||
|
@ -65,7 +65,7 @@ export class VNode {
|
||||||
clearChild: VNode | null = null;
|
clearChild: VNode | null = null;
|
||||||
// one tree相关属性
|
// one tree相关属性
|
||||||
isCreated: boolean = true;
|
isCreated: boolean = true;
|
||||||
oldHooks: Array<Hook<any, any>> = []; // 保存上一次执行的hook
|
oldHooks: Array<Hook<any, any>> | null = []; // 保存上一次执行的hook
|
||||||
oldState: any = null;
|
oldState: any = null;
|
||||||
oldRef: RefType | ((handle: any) => void) | null = null;
|
oldRef: RefType | ((handle: any) => void) | null = null;
|
||||||
suspenseChildThrow = false;
|
suspenseChildThrow = false;
|
||||||
|
@ -74,7 +74,7 @@ export class VNode {
|
||||||
suspenseDidCapture: boolean = false; // suspense是否捕获了异常
|
suspenseDidCapture: boolean = false; // suspense是否捕获了异常
|
||||||
promiseResolve: boolean = false; // suspense的promise是否resolve
|
promiseResolve: boolean = false; // suspense的promise是否resolve
|
||||||
|
|
||||||
path: Array<number> = []; // 保存从根到本节点的路径
|
path: string = ''; // 保存从根到本节点的路径
|
||||||
toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点
|
toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点
|
||||||
|
|
||||||
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用
|
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用
|
||||||
|
|
|
@ -78,7 +78,7 @@ export function updateVNode(vNode: VNode, vNodeProps?: any): VNode {
|
||||||
vNode.oldRef = vNode.ref;
|
vNode.oldRef = vNode.ref;
|
||||||
|
|
||||||
FlagUtils.setNoFlags(vNode);
|
FlagUtils.setNoFlags(vNode);
|
||||||
vNode.dirtyNodes = [];
|
vNode.dirtyNodes = null;
|
||||||
vNode.isCreated = false;
|
vNode.isCreated = false;
|
||||||
|
|
||||||
return vNode;
|
return vNode;
|
||||||
|
@ -143,7 +143,7 @@ export function createUndeterminedVNode(type, key, props) {
|
||||||
|
|
||||||
export function createTreeRootVNode(container) {
|
export function createTreeRootVNode(container) {
|
||||||
const vNode = newVirtualNode(TreeRoot, null, null, container);
|
const vNode = newVirtualNode(TreeRoot, null, null, container);
|
||||||
vNode.path.push(0);
|
vNode.path += 0;
|
||||||
createUpdateArray(vNode);
|
createUpdateArray(vNode);
|
||||||
return vNode;
|
return vNode;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
|
||||||
case TreeRoot:
|
case TreeRoot:
|
||||||
// 创建treeRoot
|
// 创建treeRoot
|
||||||
vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]);
|
vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]);
|
||||||
vNode.path.push(0);
|
vNode.path += 0;
|
||||||
|
|
||||||
createUpdateArray(vNode);
|
createUpdateArray(vNode);
|
||||||
break;
|
break;
|
||||||
|
@ -165,7 +165,7 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateVNodePath(vNode: VNode) {
|
export function updateVNodePath(vNode: VNode) {
|
||||||
vNode.path = [...vNode.parent.path, vNode.cIndex];
|
vNode.path = vNode.parent.path + vNode.cIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createVNodeFromElement(element: JSXElement): VNode {
|
export function createVNodeFromElement(element: JSXElement): VNode {
|
||||||
|
|
|
@ -79,28 +79,24 @@ export function travelVNodeTree(
|
||||||
export function clearVNode(vNode: VNode) {
|
export function clearVNode(vNode: VNode) {
|
||||||
vNode.child = null;
|
vNode.child = null;
|
||||||
vNode.next = null;
|
vNode.next = null;
|
||||||
vNode.depContexts = [];
|
vNode.depContexts = null;
|
||||||
vNode.dirtyNodes = [];
|
vNode.dirtyNodes = null;
|
||||||
vNode.state = null;
|
vNode.state = null;
|
||||||
vNode.hooks = [];
|
vNode.hooks = null;
|
||||||
vNode.suspenseChildStatus = '';
|
|
||||||
vNode.props = null;
|
vNode.props = null;
|
||||||
vNode.parent = null;
|
vNode.parent = null;
|
||||||
vNode.suspensePromises = null;
|
vNode.suspensePromises = null;
|
||||||
vNode.changeList = null;
|
vNode.changeList = null;
|
||||||
vNode.effectList = [];
|
vNode.effectList = null;
|
||||||
vNode.updates = null;
|
vNode.updates = null;
|
||||||
vNode.realNode = null;
|
vNode.realNode = null;
|
||||||
|
|
||||||
vNode.oldProps = null;
|
vNode.oldProps = null;
|
||||||
vNode.oldHooks = [];
|
vNode.oldHooks = null;
|
||||||
vNode.oldState = null;
|
vNode.oldState = null;
|
||||||
vNode.oldRef = null;
|
vNode.oldRef = null;
|
||||||
vNode.suspenseChildThrow = false;
|
|
||||||
vNode.oldSuspenseChildStatus = '';
|
|
||||||
vNode.oldChild = null;
|
vNode.oldChild = null;
|
||||||
|
|
||||||
vNode.path = [];
|
|
||||||
vNode.toUpdateNodes = null;
|
vNode.toUpdateNodes = null;
|
||||||
|
|
||||||
vNode.belongClassVNode = null;
|
vNode.belongClassVNode = null;
|
||||||
|
|
Loading…
Reference in New Issue