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