From 290f2097c5a8a5e16da239d14280bb736f74ee7b Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 10:52:12 +0800 Subject: [PATCH 1/9] Match-id-5cdfec2ac913c704d26e3fc47a3d41f0c6d6382f --- libs/horizon/src/renderer/vnode/VNode.ts | 12 ++++++------ libs/horizon/src/renderer/vnode/VNodeUtils.ts | 14 +++++--------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index e5a848de..9c9fd8e2 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -25,17 +25,17 @@ export class VNode { suspensePromises: any = null; // suspense组件的promise列表 changeList: any = null; // DOM的变更列表 - effectList: any[] = []; // useEffect 的更新数组 + effectList: any[] | null = []; // useEffect 的更新数组 updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组 - stateCallbacks: any[] = []; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 + stateCallbacks: any[] | null = []; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 isForceUpdate: boolean = false; // 是否使用强制更新 state: any = null; // ClassComponent和TreeRoot的状态 - hooks: Array> = []; // 保存hook + hooks: Array> | null = []; // 保存hook suspenseChildStatus: string = ''; // Suspense的Children是否显示 - depContexts: Array> = []; // FunctionComponent和ClassComponent对context的依赖列表 + depContexts: Array> | null = []; // FunctionComponent和ClassComponent对context的依赖列表 isDepContextChange: boolean = false; // context是否变更 - dirtyNodes: Array = []; // 需要改动的节点数组 + dirtyNodes: Array | 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 + oldHooks: Array> | null = []; // 保存上一次执行的hook oldState: any = null; oldRef: RefType | ((handle: any) => void) | null = null; suspenseChildThrow = false; diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index dc38b93e..82ad3ec8 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -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; From 3f08ed229f0a77a028b94e0b467554bf5c8f97da Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 10:55:53 +0800 Subject: [PATCH 2/9] Match-id-a4195774976a6bab660ca01ecef0e20e8c93baf6 --- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- libs/horizon/src/renderer/vnode/VNodeCreator.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 9c9fd8e2..0270165b 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -74,7 +74,7 @@ export class VNode { suspenseDidCapture: boolean = false; // suspense是否捕获了异常 promiseResolve: boolean = false; // suspense的promise是否resolve - path: Array = []; // 保存从根到本节点的路径 + path: string = ''; // 保存从根到本节点的路径 toUpdateNodes: Set | null = null; // 保存要更新的节点 belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode,处理ref的时候使用 diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index 11abe1b1..40b5cc97 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -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 { From 9a1b0add4be9694efdaf9d9072d1f573b09d5460 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:08:43 +0800 Subject: [PATCH 3/9] Match-id-008af88bfa5eb7487150476ddae80d57f9c57b0a --- libs/horizon/src/renderer/ErrorHandler.ts | 2 +- libs/horizon/src/renderer/TreeBuilder.ts | 14 ++++++++++++-- .../src/renderer/diff/nodeDiffComparator.ts | 4 ++++ libs/horizon/src/renderer/submit/Submit.ts | 10 +++++++--- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- libs/horizon/src/renderer/vnode/VNodeCreator.ts | 2 +- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/libs/horizon/src/renderer/ErrorHandler.ts b/libs/horizon/src/renderer/ErrorHandler.ts index 3c3305c1..991ef861 100644 --- a/libs/horizon/src/renderer/ErrorHandler.ts +++ b/libs/horizon/src/renderer/ErrorHandler.ts @@ -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') { diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 3c9b729b..9ff1cd0d 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -57,10 +57,20 @@ function resetProcessingVariables(startUpdateVNode: VNode) { // 收集有变化的节点,在submit阶段继续处理 function collectDirtyNodes(vNode: VNode, parent: VNode): void { // 将子树和此vNode的所有效果附加到父树的效果列表中,子项的完成顺序会影响副作用顺序。 - parent.dirtyNodes.push(...vNode.dirtyNodes); + if (vNode.dirtyNodes !== null && vNode.dirtyNodes.length) { + if (parent.dirtyNodes === null) { + parent.dirtyNodes = [...vNode.dirtyNodes]; + } else { + parent.dirtyNodes.push(...vNode.dirtyNodes); + } + } if (FlagUtils.hasAnyFlag(vNode)) { - parent.dirtyNodes.push(vNode); + if (parent.dirtyNodes === null) { + parent.dirtyNodes = [vNode]; + } else { + parent.dirtyNodes.push(vNode); + } } } diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts index 797687b5..0d65c816 100644 --- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts +++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts @@ -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); } diff --git a/libs/horizon/src/renderer/submit/Submit.ts b/libs/horizon/src/renderer/submit/Submit.ts index e222564f..7fccbe41 100644 --- a/libs/horizon/src/renderer/submit/Submit.ts +++ b/libs/horizon/src/renderer/submit/Submit.ts @@ -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,7 @@ export function submitToRender(treeRoot) { // after submit阶段 afterSubmit(dirtyNodes); - setExecuteMode(preMode) + setExecuteMode(preMode); } if (isSchedulingEffects()) { diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 0270165b..c875fe5a 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -35,7 +35,7 @@ export class VNode { suspenseChildStatus: string = ''; // Suspense的Children是否显示 depContexts: Array> | null = []; // FunctionComponent和ClassComponent对context的依赖列表 isDepContextChange: boolean = false; // context是否变更 - dirtyNodes: Array | null = []; // 需要改动的节点数组 + dirtyNodes: Array | null = null; // 需要改动的节点数组 shouldUpdate: boolean = false; childShouldUpdate: boolean = false; outerDom: any; diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index 40b5cc97..2d6d3bb2 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -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; From 32d31738b71edf23dc05bf28e4f69801b607e7cf Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:12:47 +0800 Subject: [PATCH 4/9] Match-id-07694f7bc016fe0cfd4ed0c37eae556bdf18cc58 --- libs/horizon/src/renderer/TreeBuilder.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 9ff1cd0d..020b58b2 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -57,12 +57,15 @@ function resetProcessingVariables(startUpdateVNode: VNode) { // 收集有变化的节点,在submit阶段继续处理 function collectDirtyNodes(vNode: VNode, parent: VNode): void { // 将子树和此vNode的所有效果附加到父树的效果列表中,子项的完成顺序会影响副作用顺序。 - if (vNode.dirtyNodes !== null && vNode.dirtyNodes.length) { + 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)) { From 21e1ab6595da8c0233794b25aecf985d82f3f39c Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:17:20 +0800 Subject: [PATCH 5/9] Match-id-76c4bd08e76f99dec2a23ee3bb9ce802c95eebe1 --- libs/horizon/src/renderer/submit/Submit.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/horizon/src/renderer/submit/Submit.ts b/libs/horizon/src/renderer/submit/Submit.ts index 7fccbe41..30fee9d8 100644 --- a/libs/horizon/src/renderer/submit/Submit.ts +++ b/libs/horizon/src/renderer/submit/Submit.ts @@ -65,6 +65,8 @@ export function submitToRender(treeRoot) { afterSubmit(dirtyNodes); setExecuteMode(preMode); + dirtyNodes.length = 0; + startVNode.dirtyNodes = null; } if (isSchedulingEffects()) { From c702a1b3cb492fd9e4de8acd4bd11bc63ab0527a Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:21:16 +0800 Subject: [PATCH 6/9] Match-id-a7deb6aa15e1e093aabaadcff3b378abd79319d7 --- .../src/renderer/submit/HookEffectHandler.ts | 99 ++++++++++--------- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/libs/horizon/src/renderer/submit/HookEffectHandler.ts b/libs/horizon/src/renderer/submit/HookEffectHandler.ts index b6706389..f1811d93 100644 --- a/libs/horizon/src/renderer/submit/HookEffectHandler.ts +++ b/libs/horizon/src/renderer/submit/HookEffectHandler.ts @@ -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(); + } + }); + } } diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index c875fe5a..313b5a61 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -25,7 +25,7 @@ export class VNode { suspensePromises: any = null; // suspense组件的promise列表 changeList: any = null; // DOM的变更列表 - effectList: any[] | null = []; // useEffect 的更新数组 + effectList: any[] | null = null; // useEffect 的更新数组 updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组 stateCallbacks: any[] | null = []; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 isForceUpdate: boolean = false; // 是否使用强制更新 From 0a952e800a2c76c55ae625dedf95eb903853c9d4 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:23:58 +0800 Subject: [PATCH 7/9] Match-id-e6fbf97ee32697280c273be5bc3a8b5f1605f1c9 --- libs/horizon/src/renderer/UpdateHandler.ts | 6 +++++- .../src/renderer/submit/LifeCycleHandler.ts | 15 ++++++++------- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libs/horizon/src/renderer/UpdateHandler.ts b/libs/horizon/src/renderer/UpdateHandler.ts index d00f3ce9..a2b55485 100644 --- a/libs/horizon/src/renderer/UpdateHandler.ts +++ b/libs/horizon/src/renderer/UpdateHandler.ts @@ -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); + } } } diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index be4152d1..354a179e 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -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); + } + }); + } } // 调用界面变化后的生命周期 diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 313b5a61..bf4aca7e 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -27,7 +27,7 @@ export class VNode { changeList: any = null; // DOM的变更列表 effectList: any[] | null = null; // useEffect 的更新数组 updates: any[] | null = null; // TreeRoot和ClassComponent使用的更新数组 - stateCallbacks: any[] | null = []; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 + stateCallbacks: any[] | null = null; // 存放存在setState的第二个参数和HorizonDOM.render的第三个参数所在的node数组 isForceUpdate: boolean = false; // 是否使用强制更新 state: any = null; // ClassComponent和TreeRoot的状态 From b27cb830dc09b3b6d46fe2f047aeb0d52a967ad5 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:28:20 +0800 Subject: [PATCH 8/9] Match-id-b1728f3e2e13d0dceaec7d800af945630574e9f8 --- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index bf4aca7e..25b12511 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -31,7 +31,7 @@ export class VNode { isForceUpdate: boolean = false; // 是否使用强制更新 state: any = null; // ClassComponent和TreeRoot的状态 - hooks: Array> | null = []; // 保存hook + hooks: Array> | null = null; // 保存hook suspenseChildStatus: string = ''; // Suspense的Children是否显示 depContexts: Array> | null = []; // FunctionComponent和ClassComponent对context的依赖列表 isDepContextChange: boolean = false; // context是否变更 From 3410a9cc0047e2f6431ae6a6cbe65d0b277518c0 Mon Sep 17 00:00:00 2001 From: * <8> Date: Thu, 17 Feb 2022 11:34:11 +0800 Subject: [PATCH 9/9] Match-id-2a4d49b90b105db41f89732a409a878541bd1263 --- .../src/renderer/components/context/Context.ts | 12 +++++++----- libs/horizon/src/renderer/render/ContextProvider.ts | 2 +- libs/horizon/src/renderer/vnode/VNode.ts | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libs/horizon/src/renderer/components/context/Context.ts b/libs/horizon/src/renderer/components/context/Context.ts index bcbc4f83..4052a0ed 100644 --- a/libs/horizon/src/renderer/components/context/Context.ts +++ b/libs/horizon/src/renderer/components/context/Context.ts @@ -4,17 +4,19 @@ import {throwNotInFuncError} from '../../hooks/BaseHook'; // 重置依赖 export function resetDepContexts(vNode: VNode): void { - vNode.depContexts = []; + vNode.depContexts = null; } // 收集依赖 function collectDeps(vNode: VNode, context: ContextType) { 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); + } } } diff --git a/libs/horizon/src/renderer/render/ContextProvider.ts b/libs/horizon/src/renderer/render/ContextProvider.ts index c31a9ff4..c3c287d8 100644 --- a/libs/horizon/src/renderer/render/ContextProvider.ts +++ b/libs/horizon/src/renderer/render/ContextProvider.ts @@ -50,7 +50,7 @@ function handleContextChange(processing: VNode, context: ContextType): void // 从vNode开始遍历 travelVNodeTree(vNode, node => { const depContexts = node.depContexts; - if (depContexts.length) { + if (depContexts && depContexts.length) { isMatch = matchDependencies(depContexts, context, node) ?? isMatch; } }, node => diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 25b12511..8ce6d94b 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -33,7 +33,7 @@ export class VNode { state: any = null; // ClassComponent和TreeRoot的状态 hooks: Array> | null = null; // 保存hook suspenseChildStatus: string = ''; // Suspense的Children是否显示 - depContexts: Array> | null = []; // FunctionComponent和ClassComponent对context的依赖列表 + depContexts: Array> | null = null; // FunctionComponent和ClassComponent对context的依赖列表 isDepContextChange: boolean = false; // context是否变更 dirtyNodes: Array | null = null; // 需要改动的节点数组 shouldUpdate: boolean = false;