diff --git a/libs/horizon/src/renderer/ContextSaver.ts b/libs/horizon/src/renderer/ContextSaver.ts index ef243cce..6fd6ef9a 100644 --- a/libs/horizon/src/renderer/ContextSaver.ts +++ b/libs/horizon/src/renderer/ContextSaver.ts @@ -1,6 +1,6 @@ /** * 保存与深度遍历相关的一些context。 - * 在深度遍历过程中,begin阶段会修改一些全局的值,在complete阶段会恢复。 + * 在深度遍历过程中,capture阶段会修改一些全局的值,在bubble阶段会恢复。 */ import type { VNode, ContextType } from './Types'; @@ -11,98 +11,50 @@ import { ContextProvider } from './vnode/VNodeTags'; // 保存的是“http://www.w3.org/1999/xhtml”或“http://www.w3.org/2000/svg”, // 用于识别是使用document.createElement()还是使用document.createElementNS()创建DOM -const CTX_NAMESPACE = 'CTX_NAMESPACE'; - -// 保存的是Horizon.createContext()的值,或Provider重新设置的值 -const CTX_CONTEXT = 'CTX_CONTEXT'; - -// 旧版context API,是否更改。 -const CTX_OLD_CHANGE = 'CTX_OLD_CHANGE'; -let ctxOldChange = false; let ctxNamespace = ''; -function setContext(vNode: VNode, contextName, value) { - if (vNode.contexts === null) { - vNode.contexts = { - [contextName]: value, - }; - } else { - vNode.contexts[contextName] = value; - } -} - -function getContext(vNode: VNode, contextName) { - if (vNode.contexts !== null) { - return vNode.contexts[contextName]; - } -} - // capture阶段设置 -function setNamespaceCtx(vNode: VNode, dom?: Container) { +export function setNamespaceCtx(vNode: VNode, dom?: Container) { const nextContext = getNSCtx(ctxNamespace, vNode.type, dom); - setContext(vNode, CTX_NAMESPACE, ctxNamespace); + vNode.context = ctxNamespace; + ctxNamespace = nextContext; } // bubble阶段恢复 -function resetNamespaceCtx(vNode: VNode) { - ctxNamespace = getContext(vNode, CTX_NAMESPACE); +export function resetNamespaceCtx(vNode: VNode) { + ctxNamespace = vNode.context; } -function getNamespaceCtx(): string { +export function getNamespaceCtx(): string { return ctxNamespace; } -function setContextCtx(providerVNode: VNode, nextValue: T) { +export function setContext(providerVNode: VNode, nextValue: T) { const context: ContextType = providerVNode.type._context; - setContext(providerVNode, CTX_CONTEXT, context.value); + providerVNode.context = context.value; + context.value = nextValue; } -function resetContextCtx(providerVNode: VNode) { +export function resetContext(providerVNode: VNode) { const context: ContextType = providerVNode.type._context; - context.value = getContext(providerVNode, CTX_CONTEXT); + context.value = providerVNode.context; } // 在局部更新时,恢复父节点的context -function recoverParentsContextCtx(vNode: VNode) { +export function recoverParentContext(vNode: VNode) { let parent = vNode.parent; while (parent !== null) { if (parent.tag === ContextProvider) { - const newValue = parent.props.value; - setContextCtx(parent, newValue); + parent.context = parent.props.value; } parent = parent.parent; } } -function setContextChangeCtx(providerVNode: VNode, didChange: boolean) { - setContext(providerVNode, CTX_OLD_CHANGE, didChange); - ctxOldChange = didChange; -} - -function getContextChangeCtx() { - return ctxOldChange; -} - -function resetContextChangeCtx(vNode: VNode) { - ctxOldChange = getContext(vNode, CTX_OLD_CHANGE); -} - -export { - getNamespaceCtx, - resetNamespaceCtx, - setNamespaceCtx, - setContextCtx, - resetContextCtx, - recoverParentsContextCtx, - setContextChangeCtx, - getContextChangeCtx, - resetContextChangeCtx, -}; - diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 721bbff6..1680c949 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -29,7 +29,7 @@ import { isExecuting, setExecuteMode } from './ExecuteMode'; -import { recoverParentsContextCtx, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver'; +import { recoverParentContext, resetNamespaceCtx, setNamespaceCtx } from './ContextSaver'; import { updateChildShouldUpdate, updateParentsChildShouldUpdate, @@ -231,7 +231,7 @@ function buildVNodeTree(treeRoot: VNode) { } // 恢复父节点的context - recoverParentsContextCtx(startVNode); + recoverParentContext(startVNode); } // 重置环境变量,为重新进行深度遍历做准备 diff --git a/libs/horizon/src/renderer/render/BaseComponent.ts b/libs/horizon/src/renderer/render/BaseComponent.ts index 94e5ecf4..73749909 100644 --- a/libs/horizon/src/renderer/render/BaseComponent.ts +++ b/libs/horizon/src/renderer/render/BaseComponent.ts @@ -7,7 +7,7 @@ import { TreeRoot, SuspenseComponent, } from '../vnode/VNodeTags'; -import { getContextChangeCtx, setContextCtx, setNamespaceCtx } from '../ContextSaver'; +import { setContext, setNamespaceCtx } from '../ContextSaver'; import { FlagUtils } from '../vnode/VNodeFlags'; import {onlyUpdateChildVNodes} from '../vnode/VNodeCreator'; import componentRenders from './index'; @@ -26,7 +26,7 @@ function handlerContext(processing: VNode) { break; case ContextProvider: { const newValue = processing.props.value; - setContextCtx(processing, newValue); + setContext(processing, newValue); break; } // No Default @@ -41,7 +41,6 @@ export function captureVNode(processing: VNode): VNode | null { if ( !processing.isCreated && processing.oldProps === processing.props && - !getContextChangeCtx() && !processing.shouldUpdate ) { // 复用还需对stack进行处理 diff --git a/libs/horizon/src/renderer/render/ClassComponent.ts b/libs/horizon/src/renderer/render/ClassComponent.ts index f0056f04..2856ecf9 100644 --- a/libs/horizon/src/renderer/render/ClassComponent.ts +++ b/libs/horizon/src/renderer/render/ClassComponent.ts @@ -18,7 +18,6 @@ import { markRef } from './BaseComponent'; import { processUpdates, } from '../UpdateHandler'; -import { getContextChangeCtx } from '../ContextSaver'; import { setProcessingClassVNode } from '../GlobalVar'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator'; @@ -87,7 +86,7 @@ function callUpdateLifeCycle(processing: VNode, nextProps: object, clazz) { } } -function markLifeCycle(processing: VNode, nextProps: object, shouldUpdate: Boolean) { +function markLifeCycle(processing: VNode, nextProps: object, shouldUpdate: boolean) { if (processing.isCreated) { markComponentDidMount(processing); } else if (processing.state !== processing.oldState || shouldUpdate) { @@ -136,7 +135,6 @@ export function captureRender(processing: VNode): VNode | null { // 如果 props, state, context 都没有变化且 isForceUpdate 为 false则不需要更新 shouldUpdate = oldProps !== processing.props || inst.state !== processing.state || - getContextChangeCtx() || processing.isForceUpdate; if (shouldUpdate) { @@ -172,4 +170,4 @@ export function captureRender(processing: VNode): VNode | null { } } -export function bubbleRender(processing: VNode) {} +export function bubbleRender() {} diff --git a/libs/horizon/src/renderer/render/ContextProvider.ts b/libs/horizon/src/renderer/render/ContextProvider.ts index 24aaa9f4..42058bb8 100644 --- a/libs/horizon/src/renderer/render/ContextProvider.ts +++ b/libs/horizon/src/renderer/render/ContextProvider.ts @@ -4,9 +4,8 @@ import { isSame } from '../utils/compare'; import { ClassComponent, ContextProvider } from '../vnode/VNodeTags'; import { pushForceUpdate } from '../UpdateHandler'; import { - getContextChangeCtx, - resetContextCtx, - setContextCtx, + resetContext, + setContext, } from '../ContextSaver'; import { travelVNodeTree } from '../vnode/VNodeUtils'; import { launchUpdateFromVNode } from '../TreeBuilder'; @@ -75,14 +74,14 @@ function captureContextProvider(processing: VNode): VNode | null { const newCtx = newProps.value; // 更新processing的context值为newProps.value - setContextCtx(processing, newCtx); + setContext(processing, newCtx); if (oldProps !== null) { const oldCtx = oldProps.value; const isSameContext = isSame(oldCtx, newCtx); if (isSameContext) { // context没有改变,复用 - if (oldProps.children === newProps.children && !getContextChangeCtx()) { + if (oldProps.children === newProps.children) { return onlyUpdateChildVNodes(processing); } } else { @@ -101,6 +100,6 @@ export function captureRender(processing: VNode): VNode | null { } export function bubbleRender(processing: VNode) { - resetContextCtx(processing); + resetContext(processing); } diff --git a/libs/horizon/src/renderer/render/ForwardRef.ts b/libs/horizon/src/renderer/render/ForwardRef.ts index 35680a3f..ead06587 100644 --- a/libs/horizon/src/renderer/render/ForwardRef.ts +++ b/libs/horizon/src/renderer/render/ForwardRef.ts @@ -1,8 +1,8 @@ import type {VNode} from '../Types'; import {captureRender as funCaptureRender} from './FunctionComponent'; -export function captureRender(processing: VNode, shouldUpdate?: boolean): VNode | null { - return funCaptureRender(processing, shouldUpdate); +export function captureRender(processing: VNode): VNode | null { + return funCaptureRender(processing); } export function bubbleRender() {} diff --git a/libs/horizon/src/renderer/render/FunctionComponent.ts b/libs/horizon/src/renderer/render/FunctionComponent.ts index 563cda52..128f100e 100644 --- a/libs/horizon/src/renderer/render/FunctionComponent.ts +++ b/libs/horizon/src/renderer/render/FunctionComponent.ts @@ -5,7 +5,6 @@ import { resetDepContexts } from '../components/context/Context'; import { runFunctionWithHooks } from '../hooks/HookMain'; import { ForwardRef } from '../vnode/VNodeTags'; import { FlagUtils, Update } from '../vnode/VNodeFlags'; -import { getContextChangeCtx } from '../ContextSaver'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator'; @@ -16,22 +15,10 @@ export function bubbleRender() { } // 判断children是否可以复用 -function checkIfCanReuseChildren(processing: VNode, shouldUpdate?: boolean) { - let isCanReuse = true; - - if (!processing.isCreated) { - const oldProps = processing.oldProps; - const newProps = processing.props; - - // 如果props或者context改变了 - if (oldProps !== newProps || getContextChangeCtx() || processing.isDepContextChange) { - isCanReuse = false; - } - } else { - isCanReuse = false; - } - - return isCanReuse; +function checkIfCanReuseChildren(processing: VNode) { + return !processing.isCreated && + processing.oldProps === processing.props && + !processing.isDepContextChange; } export function setStateChange(isUpdate) { @@ -46,7 +33,6 @@ export function captureFunctionComponent( processing: VNode, funcComp: any, nextProps: any, - shouldUpdate?: boolean, ) { // 函数组件内已完成异步动作 if (processing.isSuspended) { @@ -58,7 +44,7 @@ export function captureFunctionComponent( } resetDepContexts(processing); - const isCanReuse = checkIfCanReuseChildren(processing, shouldUpdate); + const isCanReuse = checkIfCanReuseChildren(processing); // 在执行exeFunctionHook前先设置stateChange为false setStateChange(false); @@ -80,7 +66,7 @@ export function captureFunctionComponent( return processing.child; } -export function captureRender(processing: VNode, shouldUpdate?: boolean): VNode | null { +export function captureRender(processing: VNode): VNode | null { const Component = processing.type; const unresolvedProps = processing.props; const resolvedProps = @@ -92,7 +78,6 @@ export function captureRender(processing: VNode, shouldUpdate?: boolean): VNode processing, Component, resolvedProps, - shouldUpdate, ); } diff --git a/libs/horizon/src/renderer/render/SuspenseComponent.ts b/libs/horizon/src/renderer/render/SuspenseComponent.ts index 225312aa..b57bef99 100644 --- a/libs/horizon/src/renderer/render/SuspenseComponent.ts +++ b/libs/horizon/src/renderer/render/SuspenseComponent.ts @@ -1,17 +1,16 @@ -import type {VNode, PromiseType} from '../Types'; +import type { VNode, PromiseType } from '../Types'; -import {FlagUtils, Interrupted} from '../vnode/VNodeFlags'; -import {onlyUpdateChildVNodes, updateVNode, createFragmentVNode} from '../vnode/VNodeCreator'; +import { FlagUtils, Interrupted } from '../vnode/VNodeFlags'; +import { onlyUpdateChildVNodes, updateVNode, createFragmentVNode } from '../vnode/VNodeCreator'; import { ClassComponent, ForwardRef, FunctionComponent, SuspenseComponent, } from '../vnode/VNodeTags'; -import {pushForceUpdate} from '../UpdateHandler'; -import {launchUpdateFromVNode, tryRenderFromRoot} from '../TreeBuilder'; -import {updateShouldUpdateOfTree} from '../vnode/VNodeShouldUpdate'; -import {getContextChangeCtx} from '../ContextSaver'; +import { pushForceUpdate } from '../UpdateHandler'; +import { launchUpdateFromVNode, tryRenderFromRoot } from '../TreeBuilder'; +import { updateShouldUpdateOfTree } from '../vnode/VNodeShouldUpdate'; import { markVNodePath } from '../utils/vNodePath'; export enum SuspenseChildStatus { @@ -101,7 +100,7 @@ export function captureSuspenseComponent(processing: VNode) { } function updateFallback(processing: VNode): Array | VNode | null { - const childFragment: VNode | null= processing.child; + const childFragment: VNode | null = processing.child; if (childFragment?.childShouldUpdate) { if (processing.suspenseState.promiseResolved) { @@ -130,7 +129,6 @@ export function captureRender(processing: VNode, shouldUpdate: boolean): Array