From da66b70642f17b759de01e2e34ce6e3a604db947 Mon Sep 17 00:00:00 2001 From: * <8> Date: Wed, 30 Mar 2022 17:37:46 +0800 Subject: [PATCH] Match-id-1e7778df481951bd1082406e28f7713d3ca5e6b6 --- .../src/renderer/render/ClassComponent.ts | 13 ++++----- .../render/IncompleteClassComponent.ts | 27 ------------------- .../src/renderer/render/SuspenseComponent.ts | 3 +-- libs/horizon/src/renderer/render/index.ts | 3 --- .../src/renderer/submit/LifeCycleHandler.ts | 19 ++++++------- libs/horizon/src/renderer/vnode/VNode.ts | 3 --- libs/horizon/src/renderer/vnode/VNodeUtils.ts | 1 - 7 files changed, 18 insertions(+), 51 deletions(-) delete mode 100644 libs/horizon/src/renderer/render/IncompleteClassComponent.ts diff --git a/libs/horizon/src/renderer/render/ClassComponent.ts b/libs/horizon/src/renderer/render/ClassComponent.ts index 228ae62a..f0056f04 100644 --- a/libs/horizon/src/renderer/render/ClassComponent.ts +++ b/libs/horizon/src/renderer/render/ClassComponent.ts @@ -106,6 +106,13 @@ export function captureRender(processing: VNode): VNode | null { resetDepContexts(processing); + // suspense打断后,再次render只需初次渲染 + if (processing.isSuspended) { + mountInstance(ctor, processing, nextProps); + processing.isSuspended = false; + return createChildren(ctor, processing); + } + // 通过 shouldUpdate 判断是否要复用 children,该值和props,state,context的变化,shouldComponentUpdate,forceUpdate api的调用结果有关 let shouldUpdate; const inst = processing.realNode; @@ -166,9 +173,3 @@ export function captureRender(processing: VNode): VNode | null { } export function bubbleRender(processing: VNode) {} - -// 用于未完成的类组件 -export function getIncompleteClassComponent(clazz, processing: VNode, nextProps: object): VNode | null { - mountInstance(clazz, processing, nextProps); - return createChildren(clazz, processing); -} diff --git a/libs/horizon/src/renderer/render/IncompleteClassComponent.ts b/libs/horizon/src/renderer/render/IncompleteClassComponent.ts deleted file mode 100644 index 8e02df51..00000000 --- a/libs/horizon/src/renderer/render/IncompleteClassComponent.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type {VNode} from '../Types'; - -import {mergeDefaultProps} from './LazyComponent'; -import {ClassComponent} from '../vnode/VNodeTags'; -import {resetDepContexts} from '../components/context/Context'; -import {getIncompleteClassComponent} from './ClassComponent'; - -function captureIncompleteClassComponent(processing, Component, nextProps) { - processing.tag = ClassComponent; - - resetDepContexts(processing); - - return getIncompleteClassComponent(Component, processing, nextProps); -} - -export function captureRender(processing: VNode): VNode | null { - const Component = processing.type; - const unresolvedProps = processing.props; - const resolvedProps = - processing.isLazyComponent - ? mergeDefaultProps(Component, unresolvedProps) - : unresolvedProps; - - return captureIncompleteClassComponent(processing, Component, resolvedProps); -} - -export function bubbleRender(processing: VNode) {} diff --git a/libs/horizon/src/renderer/render/SuspenseComponent.ts b/libs/horizon/src/renderer/render/SuspenseComponent.ts index 38a84fbc..225312aa 100644 --- a/libs/horizon/src/renderer/render/SuspenseComponent.ts +++ b/libs/horizon/src/renderer/render/SuspenseComponent.ts @@ -6,7 +6,6 @@ import { ClassComponent, ForwardRef, FunctionComponent, - IncompleteClassComponent, SuspenseComponent, } from '../vnode/VNodeTags'; import {pushForceUpdate} from '../UpdateHandler'; @@ -179,7 +178,7 @@ export function handleSuspenseChildThrowError(parent: VNode, processing: VNode, if (processing.tag === ClassComponent) { if (processing.isCreated) { // 渲染类组件场景,要标志未完成(否则会触发componentWillUnmount) - processing.tag = IncompleteClassComponent; + processing.isSuspended = true ; } else { // 类组件更新,标记强制更新,否则被memo等优化跳过 pushForceUpdate(processing); diff --git a/libs/horizon/src/renderer/render/index.ts b/libs/horizon/src/renderer/render/index.ts index 2b6f418d..4e300c93 100644 --- a/libs/horizon/src/renderer/render/index.ts +++ b/libs/horizon/src/renderer/render/index.ts @@ -9,7 +9,6 @@ import * as DomComponentRender from './DomComponent'; import * as DomPortalRender from './DomPortal'; import * as TreeRootRender from './TreeRoot'; import * as DomTextRender from './DomText'; -import * as IncompleteClassComponentRender from './IncompleteClassComponent'; import * as LazyComponentRender from './LazyComponent'; import * as MemoComponentRender from './MemoComponent'; import * as SuspenseComponentRender from './SuspenseComponent'; @@ -25,7 +24,6 @@ import { DomPortal, TreeRoot, DomText, - IncompleteClassComponent, LazyComponent, MemoComponent, SuspenseComponent, @@ -46,7 +44,6 @@ export default { [DomPortal]: DomPortalRender, [TreeRoot]: TreeRootRender, [DomText]: DomTextRender, - [IncompleteClassComponent]: IncompleteClassComponentRender, [LazyComponent]: LazyComponentRender, [MemoComponent]: MemoComponentRender, [SuspenseComponent]: SuspenseComponentRender, diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index f4aaaddf..7201613d 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -32,7 +32,7 @@ import { callEffectRemove, callUseEffects, callUseLayoutEffectCreate, - callUseLayoutEffectRemove + callUseLayoutEffectRemove, } from './HookEffectHandler'; import { handleSubmitError } from '../ErrorHandler'; import { @@ -192,7 +192,8 @@ function unmountVNode(vNode: VNode): void { const instance = vNode.realNode; // 当constructor中抛出异常时,instance会是null,这里判断一下instance是否为空 - if (instance && typeof instance.componentWillUnmount === 'function') { + // suspense打断时不需要触发WillUnmount + if (instance && typeof instance.componentWillUnmount === 'function' && !vNode.isSuspended) { callComponentWillUnmount(vNode, instance); } break; @@ -212,11 +213,11 @@ function unmountVNode(vNode: VNode): void { // 卸载vNode,递归遍历子vNode function unmountNestedVNodes(vNode: VNode): void { travelVNodeTree(vNode, (node) => { - unmountVNode(node); - }, node => - // 如果是DomPortal,不需要遍历child - node.tag === DomPortal - , vNode, null); + unmountVNode(node); + }, node => + // 如果是DomPortal,不需要遍历child + node.tag === DomPortal + , vNode, null); } function submitAddition(vNode: VNode): void { @@ -329,7 +330,7 @@ function submitClear(vNode: VNode): void { // 但考虑到用户可能自定义其他属性,所以采用遍历赋值的方式 const customizeKeys = Object.keys(realNode); const keyLength = customizeKeys.length; - for(let i = 0; i < keyLength; i++) { + for (let i = 0; i < keyLength; i++) { const key = customizeKeys[i]; // 测试代码 mock 实例的全部可遍历属性都会被Object.keys方法读取到 // children 属性被复制意味着复制了子节点,因此要排除 @@ -351,7 +352,7 @@ function submitClear(vNode: VNode): void { } let clearChild = vNode.clearChild as VNode; // 上次渲染的child保存在clearChild属性中 // 卸载 clearChild 和 它的兄弟节点 - while(clearChild) { + while (clearChild) { // 卸载子vNode,递归遍历子vNode unmountNestedVNodes(clearChild); clearVNode(clearChild); diff --git a/libs/horizon/src/renderer/vnode/VNode.ts b/libs/horizon/src/renderer/vnode/VNode.ts index 166c8c61..7189db06 100644 --- a/libs/horizon/src/renderer/vnode/VNode.ts +++ b/libs/horizon/src/renderer/vnode/VNode.ts @@ -16,7 +16,6 @@ import { ContextProvider, Profiler, MemoComponent, - IncompleteClassComponent, } from './VNodeTags'; import type { VNodeTag } from './VNodeTags'; import type { RefType, ContextType, SuspenseState } from '../Types'; @@ -158,8 +157,6 @@ export class VNode { break; case Profiler: break; - case IncompleteClassComponent: - break; } } } diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index d064b38c..2875a125 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -82,7 +82,6 @@ export function clearVNode(vNode: VNode) { vNode.hooks = null; vNode.props = null; vNode.parent = null; - // mark vNode.suspenseState = null; vNode.changeList = null; vNode.effectList = null;