Match-id-49b2f36cda8b4bb3c0bd2f10fba05d43d5cf72ea

This commit is contained in:
* 2022-01-21 10:30:44 +08:00 committed by *
commit e43fb0fd5e
24 changed files with 129 additions and 119 deletions

View File

@ -14,14 +14,13 @@ import {
TreeRoot, TreeRoot,
} from '../renderer/vnode/VNodeTags'; } from '../renderer/vnode/VNodeTags';
const suffixKey = new Date().getTime().toString();
const prefix = '_horizon'; const prefix = '_horizon';
const internalKeys = { const internalKeys = {
VNode: `${prefix}VNode@${suffixKey}`, VNode: `${prefix}VNode`,
props: `${prefix}Props@${suffixKey}`, props: `${prefix}Props`,
events: `${prefix}Events@${suffixKey}`, events: `${prefix}Events`,
nonDelegatedEvents: `${prefix}NonDelegatedEvents@${suffixKey}`, nonDelegatedEvents: `${prefix}NonDelegatedEvents`,
}; };
// 通过 VNode 实例获取 DOM 节点 // 通过 VNode 实例获取 DOM 节点

View File

@ -1,7 +1,7 @@
import {throwIfTrue} from '../renderer/utils/throwIfTrue'; import {throwIfTrue} from '../renderer/utils/throwIfTrue';
import {TYPE_ELEMENT, TYPE_PORTAL} from '../renderer/utils/elementType'; import {TYPE_COMMON_ELEMENT, TYPE_PORTAL} from './JSXElementType';
import {isValidElement, HorizonElement} from './HorizonElement'; import {isValidElement, JSXElement} from './JSXElement';
// 生成key // 生成key
function getItemKey(item: any, index: number): string { function getItemKey(item: any, index: number): string {
@ -49,11 +49,11 @@ function callMapFun(
? '.$' + mappedChild.key ? '.$' + mappedChild.key
: ''); : '');
// 返回一个修改key的children // 返回一个修改key的children
mappedChild = HorizonElement( mappedChild = JSXElement(
mappedChild.type, mappedChild.type,
newKey, newKey,
mappedChild.ref, mappedChild.ref,
mappedChild._vNode, mappedChild.belongClassVNode,
mappedChild.props, mappedChild.props,
); );
} }
@ -84,7 +84,7 @@ function mapChildrenToArray(
return; return;
} }
const vtype = children.vtype; const vtype = children.vtype;
if (vtype === TYPE_ELEMENT || vtype === TYPE_PORTAL) { if (vtype === TYPE_COMMON_ELEMENT || vtype === TYPE_PORTAL) {
callMapFun(children, arr, prefix, callback) ; callMapFun(children, arr, prefix, callback) ;
return; return;
} }

View File

@ -3,7 +3,7 @@ import {
TYPE_PROFILER, TYPE_PROFILER,
TYPE_STRICT_MODE, TYPE_STRICT_MODE,
TYPE_SUSPENSE, TYPE_SUSPENSE,
} from '../renderer/utils/elementType'; } from './JSXElementType';
import {Component, PureComponent} from '../renderer/components/BaseClassComponent'; import {Component, PureComponent} from '../renderer/components/BaseClassComponent';
import {createRef} from '../renderer/components/CreateRef'; import {createRef} from '../renderer/components/CreateRef';
@ -12,7 +12,7 @@ import {
createElement, createElement,
cloneElement, cloneElement,
isValidElement, isValidElement,
} from './HorizonElement'; } from './JSXElement';
import {createContext} from '../renderer/components/context/CreateContext'; import {createContext} from '../renderer/components/context/CreateContext';
import {lazy} from '../renderer/components/Lazy'; import {lazy} from '../renderer/components/Lazy';
import {forwardRef} from '../renderer/components/ForwardRef'; import {forwardRef} from '../renderer/components/ForwardRef';

View File

@ -1,18 +1,18 @@
import { TYPE_ELEMENT } from '../renderer/utils/elementType'; import { TYPE_COMMON_ELEMENT } from './JSXElementType';
import ProcessingVNode from '../renderer/vnode/ProcessingVNode'; import { getProcessingClassVNode } from '../renderer/GlobalVar';
/** /**
* vtype element * vtype element
* type,dom节点的名称或者组件的函数地址 * type dom节点的名称或者组件的函数地址
* key key属性 * key key属性
* ref ref属性 * ref ref属性
* props * props
*/ */
export function HorizonElement(type, key, ref, vNode, props) { export function JSXElement(type, key, ref, vNode, props) {
return { return {
// Horizon元素标识符 // 元素标识符
vtype: TYPE_ELEMENT, vtype: TYPE_COMMON_ELEMENT,
// 属于元素的内置属性 // 属于元素的内置属性
type: type, type: type,
@ -20,8 +20,8 @@ export function HorizonElement(type, key, ref, vNode, props) {
ref: ref, ref: ref,
props: props, props: props,
// 记录负责创建此元素的组件。 // 所属的class组件
_vNode: vNode, belongClassVNode: vNode,
}; };
} }
@ -42,7 +42,7 @@ function buildElement(isClone, type, setting, ...children) {
const key = (setting && setting.key !== undefined) ? String(setting.key) : (isClone ? type.key : null); const key = (setting && setting.key !== undefined) ? String(setting.key) : (isClone ? type.key : null);
const ref = (setting && setting.ref !== undefined) ? setting.ref : (isClone ? type.ref : null); const ref = (setting && setting.ref !== undefined) ? setting.ref : (isClone ? type.ref : null);
const props = isClone ? {...type.props} : {}; const props = isClone ? {...type.props} : {};
let vNode = isClone ? type._vNode : ProcessingVNode.val; let vNode = isClone ? type.belongClassVNode : getProcessingClassVNode();
if (setting != null) { if (setting != null) {
Object.keys(setting).forEach(k => { Object.keys(setting).forEach(k => {
@ -51,7 +51,7 @@ function buildElement(isClone, type, setting, ...children) {
} }
}); });
if (setting.ref !== undefined && isClone) { if (setting.ref !== undefined && isClone) {
vNode = ProcessingVNode.val; vNode = getProcessingClassVNode();
} }
} }
@ -59,15 +59,15 @@ function buildElement(isClone, type, setting, ...children) {
props.children = children.length === 1 ? children[0] : children; props.children = children.length === 1 ? children[0] : children;
} }
const element = isClone ? type.type : type; const element = isClone ? type.type : type;
//合并默认属性 // 合并默认属性
if (element && element.defaultProps) { if (element && element.defaultProps) {
mergeDefault(props, element.defaultProps); mergeDefault(props, element.defaultProps);
} }
return HorizonElement(element, key, ref, vNode, props); return JSXElement(element, key, ref, vNode, props);
} }
//创建Element结构体供JSX编译时调用 // 创建Element结构体供JSX编译时调用
export function createElement(type, setting, ...children) { export function createElement(type, setting, ...children) {
return buildElement(false, type, setting, ...children); return buildElement(false, type, setting, ...children);
} }
@ -78,5 +78,5 @@ export function cloneElement(element, setting, ...children) {
// 检测结构体是否为合法的Element // 检测结构体是否为合法的Element
export function isValidElement(element) { export function isValidElement(element) {
return !!(element && element.vtype === TYPE_ELEMENT); return !!(element && element.vtype === TYPE_COMMON_ELEMENT);
} }

View File

@ -1,4 +1,4 @@
export const TYPE_ELEMENT = 1; export const TYPE_COMMON_ELEMENT = 1;
export const TYPE_PORTAL = 2; export const TYPE_PORTAL = 2;
export const TYPE_FRAGMENT = 3; export const TYPE_FRAGMENT = 3;
export const TYPE_STRICT_MODE = 4; export const TYPE_STRICT_MODE = 4;

View File

@ -5,7 +5,7 @@ export const InRender = 'IN_RENDER';
type RenderMode = typeof ByAsync | typeof BySync | typeof InRender; type RenderMode = typeof ByAsync | typeof BySync | typeof InRender;
// 当前执行阶段标记 // 当前执行模式标记
let executeMode = { let executeMode = {
[ByAsync]: false, [ByAsync]: false,
[BySync]: false, [BySync]: false,

View File

@ -0,0 +1,34 @@
import type {VNode} from './Types';
// 当前处理的classVNode用于inst.refs用法中的
let processingClassVNode: VNode | null = null;
export function getProcessingClassVNode(): VNode | null {
return processingClassVNode;
}
export function setProcessingClassVNode(vNode: VNode | null) {
processingClassVNode = vNode;
}
// 计算出来的刷新节点,不一定是根节点
let startVNode: VNode | null = null;
export function getStartVNode(): VNode | null {
return startVNode;
}
export function setStartVNode(vNode: VNode | null) {
startVNode = vNode;
}
type BuildVNodeResult = 0 | 1 | 2 | 3;
export const BuildInComplete = 0;
export const BuildFatalErrored = 1;
export const BuildErrored = 2;
export const BuildCompleted = 3;
// 根节点退出build tree时的状态如: completed, incomplete, errored, fatalErrored.
let buildVNodeResult: BuildVNodeResult = BuildInComplete;
export function setBuildResult(result: BuildVNodeResult) {
buildVNodeResult = result;
}
export function getBuildResult(): BuildVNodeResult {
return buildVNodeResult;
}

View File

@ -9,7 +9,15 @@ import { checkLoopingUpdateLimit, submitToRender } from './submit/Submit';
import { runAsyncEffects } from './submit/HookEffectHandler'; import { runAsyncEffects } from './submit/HookEffectHandler';
import { handleRenderThrowError } from './ErrorHandler'; import { handleRenderThrowError } from './ErrorHandler';
import componentRenders from './render'; import componentRenders from './render';
import ProcessingVNode from './vnode/ProcessingVNode'; import {
BuildCompleted, BuildErrored,
BuildFatalErrored,
BuildInComplete, getBuildResult,
getStartVNode,
setBuildResult,
setProcessingClassVNode,
setStartVNode
} from './GlobalVar';
import { findDomParent, getSiblingVNode } from './vnode/VNodeUtils'; import { findDomParent, getSiblingVNode } from './vnode/VNodeUtils';
import { import {
ByAsync, ByAsync,
@ -28,39 +36,16 @@ import {
updateShouldUpdateOfTree updateShouldUpdateOfTree
} from './vnode/VNodeShouldUpdate'; } from './vnode/VNodeShouldUpdate';
type BuildVNodeResult = 0 | 1 | 2 | 3;
const BuildInComplete = 0;
const BuildFatalErrored = 1;
const BuildErrored = 2;
const BuildCompleted = 3;
// 当前运行的vNode节点 // 当前运行的vNode节点
let processing: VNode | null = null; let processing: VNode | null = null;
// 根节点退出build tree时的状态如: completed, incomplete, errored, fatalErrored.
let buildVNodeResult: BuildVNodeResult = BuildInComplete;
// 不可恢复错误 // 不可恢复错误
let unrecoverableErrorDuringBuild: any = null; let unrecoverableErrorDuringBuild: any = null;
function setBuildResult(result: BuildVNodeResult) {
buildVNodeResult = result;
}
function getBuildResult(): BuildVNodeResult {
return buildVNodeResult;
}
export function setProcessing(vNode: VNode | null) { export function setProcessing(vNode: VNode | null) {
processing = vNode; processing = vNode;
} }
let startVNode: VNode | null = null;
export function getStartVNode(): VNode | null {
return startVNode;
}
export function setStartVNode(vNode: VNode | null) {
startVNode = vNode;
}
// 为重新进行深度遍历做准备 // 为重新进行深度遍历做准备
function resetProcessingVariables(startUpdateVNode: VNode) { function resetProcessingVariables(startUpdateVNode: VNode) {
// 创建processing // 创建processing
@ -141,7 +126,6 @@ function buildVNodeTree(treeRoot: VNode) {
// 计算出开始节点 // 计算出开始节点
const startUpdateVNode = calcStartUpdateVNode(treeRoot); const startUpdateVNode = calcStartUpdateVNode(treeRoot);
// 缓存起来 // 缓存起来
setStartVNode(startUpdateVNode); setStartVNode(startUpdateVNode);
@ -163,7 +147,7 @@ function buildVNodeTree(treeRoot: VNode) {
recoverParentsContextCtx(startUpdateVNode); recoverParentsContextCtx(startUpdateVNode);
} }
// 重置环境变量 // 重置环境变量,为重新进行深度遍历做准备
resetProcessingVariables(startUpdateVNode); resetProcessingVariables(startUpdateVNode);
do { do {
@ -178,9 +162,10 @@ function buildVNodeTree(treeRoot: VNode) {
} else { } else {
processing = next; processing = next;
} }
ProcessingVNode.val = null;
} }
setProcessingClassVNode(null);
break; break;
} catch (thrownValue) { } catch (thrownValue) {
handleError(treeRoot, thrownValue); handleError(treeRoot, thrownValue);

View File

@ -15,14 +15,14 @@ export type UseReducerHookType = {
}; };
export type UseContextHookType = { useContext<T>(context: ContextType<T>,): T }; export type UseContextHookType = { useContext<T>(context: ContextType<T>,): T };
export type HorizonElement = { export type JSXElement = {
vtype: any, vtype: any,
type: any, type: any,
key: any, key: any,
ref: any, ref: any,
props: any, props: any,
_vNode: any, belongClassVNode: any,
}; };
export type ProviderType<T> = { export type ProviderType<T> = {

View File

@ -1,4 +1,4 @@
import {TYPE_PORTAL} from '../utils/elementType'; import {TYPE_PORTAL} from '../../external/JSXElementType';
import type {PortalType} from '../Types'; import type {PortalType} from '../Types';
export function createPortal( export function createPortal(

View File

@ -1,4 +1,4 @@
import {TYPE_FORWARD_REF} from '../utils/elementType'; import {TYPE_FORWARD_REF} from '../../external/JSXElementType';
export function forwardRef(render: Function) { export function forwardRef(render: Function) {
return { return {

View File

@ -1,6 +1,6 @@
import type {PromiseType} from '../Types'; import type {PromiseType} from '../Types';
import {TYPE_LAZY} from '../utils/elementType'; import {TYPE_LAZY} from '../../external/JSXElementType';
enum LayStatus { enum LayStatus {
UnProcessed = 'UnProcessed', UnProcessed = 'UnProcessed',

View File

@ -1,4 +1,4 @@
import {TYPE_MEMO} from '../utils/elementType'; import {TYPE_MEMO} from '../../external/JSXElementType';
export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) { export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) {
return { return {

View File

@ -1,5 +1,5 @@
import type {ContextType} from '../../Types'; import type {ContextType} from '../../Types';
import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../utils/elementType'; import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../../external/JSXElementType';
export function createContext<T>(val: T): ContextType<T> { export function createContext<T>(val: T): ContextType<T> {
const context: ContextType<T> = { const context: ContextType<T> = {

View File

@ -1,27 +1,11 @@
import type { VNode, HorizonElement } from '../Types'; import type { VNode, JSXElement } from '../Types';
// 当前vNode和element是同样的类型 // 当前vNode和element是同样的类型
// LazyComponent 会修改type的类型所以特殊处理这种类型 // LazyComponent 会修改type的类型所以特殊处理这种类型
export const isSameType = (vNode: VNode, ele: HorizonElement) => { export const isSameType = (vNode: VNode, ele: JSXElement) => {
return vNode.type === ele.type || (vNode.isLazyComponent && vNode.lazyType === ele.type); return vNode.type === ele.type || (vNode.isLazyComponent && vNode.lazyType === ele.type);
}; };
export function createRef(element: HorizonElement): any | void {
const elementRef = element.ref;
// 如果ref是null、function、object直接返回
if (elementRef === null || typeof elementRef === 'function' || typeof elementRef === 'object') {
return elementRef;
} else { // 包装成函数
if (element._vNode) {
let inst = element._vNode.realNode;
return function(instance) {
inst.refs[String(elementRef)] = instance;
};
}
}
}
export function isTextType(newChild: any) { export function isTextType(newChild: any) {
return typeof newChild === 'string' || typeof newChild === 'number'; return typeof newChild === 'string' || typeof newChild === 'number';
} }

View File

@ -1,11 +1,10 @@
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import { FlagUtils } from '../vnode/VNodeFlags'; import { FlagUtils } from '../vnode/VNodeFlags';
import { TYPE_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../utils/elementType'; import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType';
import { DomText, DomPortal, Fragment } from '../vnode/VNodeTags'; import { DomText, DomPortal, Fragment } from '../vnode/VNodeTags';
import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator'; import {updateVNode, createVNode, createVNodeFromElement, updateVNodePath} from '../vnode/VNodeCreator';
import { import {
isSameType, isSameType,
createRef,
getIteratorFn, getIteratorFn,
isTextType, isTextType,
isArrayType, isArrayType,
@ -60,7 +59,7 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean {
if (isArrayType(newChild) || isIteratorType(newChild)) { if (isArrayType(newChild) || isIteratorType(newChild)) {
return oldKey === null; return oldKey === null;
} }
if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
return oldKey === newChild.key; return oldKey === newChild.key;
} }
} }
@ -79,7 +78,7 @@ function getNodeType(newChild: any): string {
if (isArrayType(newChild) || isIteratorType(newChild)) { if (isArrayType(newChild) || isIteratorType(newChild)) {
return DiffCategory.ARR_NODE; return DiffCategory.ARR_NODE;
} }
if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
return DiffCategory.OBJECT_NODE; return DiffCategory.OBJECT_NODE;
} }
} }
@ -129,7 +128,7 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
break; break;
} }
case DiffCategory.OBJECT_NODE: { case DiffCategory.OBJECT_NODE: {
if (newChild.vtype === TYPE_ELEMENT) { if (newChild.vtype === TYPE_COMMON_ELEMENT) {
if (newChild.type === TYPE_FRAGMENT) { if (newChild.type === TYPE_FRAGMENT) {
if (oldNode === null || oldNode.tag !== Fragment) { if (oldNode === null || oldNode.tag !== Fragment) {
const key = oldNode !== null ? oldNode.key : newChild.key; const key = oldNode !== null ? oldNode.key : newChild.key;
@ -142,10 +141,12 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) {
if (oldNode === null || !isSameType(oldNode, newChild)) { if (oldNode === null || !isSameType(oldNode, newChild)) {
resultNode = createVNodeFromElement(newChild); resultNode = createVNodeFromElement(newChild);
resultNode.ref = createRef(newChild); resultNode.ref = newChild.ref;
resultNode.belongClassVNode = newChild.belongClassVNode;
} else { } else {
resultNode = updateVNode(oldNode, newChild.props); resultNode = updateVNode(oldNode, newChild.props);
resultNode.ref = createRef(newChild); resultNode.ref = newChild.ref;
resultNode.belongClassVNode = newChild.belongClassVNode;
} }
break; break;
} else if (newChild.vtype === TYPE_PORTAL) { } else if (newChild.vtype === TYPE_PORTAL) {
@ -200,7 +201,7 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
if (isArrayType(newChild) || isIteratorType(newChild)) { if (isArrayType(newChild) || isIteratorType(newChild)) {
return nodeMap.get(newIdx) || null; return nodeMap.get(newIdx) || null;
} }
if (newChild.vtype === TYPE_ELEMENT || newChild.vtype === TYPE_PORTAL) { if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
return nodeMap.get(newChild.key === null ? newIdx : newChild.key) || null; return nodeMap.get(newChild.key === null ? newIdx : newChild.key) || null;
} }
} }
@ -539,7 +540,7 @@ function diffObjectNodeHandler(
let resultNode: VNode | null = null; let resultNode: VNode | null = null;
let startDelVNode = firstChildVNode; let startDelVNode = firstChildVNode;
if (newChild.vtype === TYPE_ELEMENT) { if (newChild.vtype === TYPE_COMMON_ELEMENT) {
if (canReuseNode) { if (canReuseNode) {
// 可以复用 // 可以复用
if (canReuseNode.tag === Fragment && newChild.type === TYPE_FRAGMENT) { if (canReuseNode.tag === Fragment && newChild.type === TYPE_FRAGMENT) {
@ -548,7 +549,8 @@ function diffObjectNodeHandler(
resultNode.next = null; resultNode.next = null;
} else if (isSameType(canReuseNode, newChild)) { } else if (isSameType(canReuseNode, newChild)) {
resultNode = updateVNode(canReuseNode, newChild.props); resultNode = updateVNode(canReuseNode, newChild.props);
resultNode.ref = createRef(newChild); resultNode.ref = newChild.ref;
resultNode.belongClassVNode = newChild.belongClassVNode;
startDelVNode = getSiblingVNode(resultNode); startDelVNode = getSiblingVNode(resultNode);
resultNode.next = null; resultNode.next = null;
} }
@ -560,7 +562,8 @@ function diffObjectNodeHandler(
resultNode = createVNode(Fragment, newChild.key, newChild.props.children); resultNode = createVNode(Fragment, newChild.key, newChild.props.children);
} else { } else {
resultNode = createVNodeFromElement(newChild); resultNode = createVNodeFromElement(newChild);
resultNode.ref = createRef(newChild); resultNode.ref = newChild.ref;
resultNode.belongClassVNode = newChild.belongClassVNode;
} }
} }
} else if (newChild.vtype === TYPE_PORTAL) { } else if (newChild.vtype === TYPE_PORTAL) {

View File

@ -27,7 +27,7 @@ import {
processUpdates, processUpdates,
} from '../UpdateHandler'; } from '../UpdateHandler';
import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver'; import { getContextChangeCtx, setContextChangeCtx } from '../ContextSaver';
import ProcessingVNode from '../vnode/ProcessingVNode'; import { setProcessingClassVNode } from '../GlobalVar';
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
// 获取当前节点的context // 获取当前节点的context
@ -69,7 +69,7 @@ function mountInstance(clazz, processing: VNode, nextProps: object) {
function createChildren(clazz: any, processing: VNode) { function createChildren(clazz: any, processing: VNode) {
markRef(processing); markRef(processing);
ProcessingVNode.val = processing; setProcessingClassVNode(processing);
processing.state = processing.realNode.state; processing.state = processing.realNode.state;
const inst = processing.realNode; const inst = processing.realNode;

View File

@ -7,7 +7,7 @@ import {
TYPE_FRAGMENT, TYPE_FRAGMENT,
TYPE_PROFILER, TYPE_PROFILER,
TYPE_STRICT_MODE, TYPE_STRICT_MODE,
} from '../utils/elementType'; } from '../../external/JSXElementType';
import {Fragment} from '../vnode/VNodeTags'; import {Fragment} from '../vnode/VNodeTags';
export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null { export function captureRender(processing: VNode, shouldUpdate: boolean): VNode | null {

View File

@ -159,13 +159,19 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
function attachRef(vNode: VNode) { function attachRef(vNode: VNode) {
const ref = vNode.ref; const ref = vNode.ref;
if (ref !== null) { if (ref !== null) {
const instance = vNode.realNode; const instance = vNode.realNode;
if (typeof ref === 'function') { let refType = typeof ref;
if (refType === 'function') {
ref(instance); ref(instance);
} else { } else if (refType === 'object') {
(<RefType>ref).current = instance; (<RefType>ref).current = instance;
} else {
if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) {
vNode.belongClassVNode.realNode.refs[String(ref)] = instance;
}
} }
} }
} }
@ -174,14 +180,20 @@ function detachRef(vNode: VNode, isOldRef?: boolean) {
let ref = (isOldRef ? vNode.oldRef : vNode.ref); let ref = (isOldRef ? vNode.oldRef : vNode.ref);
if (ref !== null) { if (ref !== null) {
if (typeof ref === 'function') { let refType = typeof ref;
if (refType === 'function') {
try { try {
ref(null); ref(null);
} catch (error) { } catch (error) {
handleSubmitError(vNode, error); handleSubmitError(vNode, error);
} }
} else { } else if (refType === 'object') {
(<RefType>ref).current = null; (<RefType>ref).current = null;
} else {
if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) {
vNode.belongClassVNode.realNode.refs[String(ref)] = null;
}
} }
} }
} }

View File

@ -11,7 +11,7 @@ import {
callBeforeSubmitLifeCycles, submitDeletion, submitAddition, callBeforeSubmitLifeCycles, submitDeletion, submitAddition,
submitResetTextContent, submitUpdate, detachRef, submitResetTextContent, submitUpdate, detachRef,
} from './LifeCycleHandler'; } from './LifeCycleHandler';
import {tryRenderRoot, setProcessing, getStartVNode} from '../TreeBuilder'; import {tryRenderRoot, setProcessing} from '../TreeBuilder';
import { import {
BySync, BySync,
InRender, InRender,
@ -24,6 +24,7 @@ import {
isSchedulingEffects, isSchedulingEffects,
setSchedulingEffects, setHookEffectRoot, setSchedulingEffects, setHookEffectRoot,
} from './HookEffectHandler'; } from './HookEffectHandler';
import {getStartVNode} from '../GlobalVar';
let rootThrowError = null; let rootThrowError = null;

View File

@ -1,8 +0,0 @@
import type {VNode} from '../Types';
// 当前所有者是应拥有当前正在构建的任何组件的组件。
const ProcessingVNode: { val: VNode | null } = {
val: null,
};
export default ProcessingVNode;

View File

@ -76,6 +76,8 @@ export class VNode {
path: Array<number> = []; // 保存从根到本节点的路径 path: Array<number> = []; // 保存从根到本节点的路径
toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点 toUpdateNodes: Set<VNode> | null = null; // 保存要更新的节点
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode处理ref的时候使用
constructor(tag: VNodeTag, props: any, key: null | string, outerDom) { constructor(tag: VNodeTag, props: any, key: null | string, outerDom) {
this.tag = tag; // 对应组件的类型比如ClassComponent等 this.tag = tag; // 对应组件的类型比如ClassComponent等
this.key = key; this.key = key;

View File

@ -24,9 +24,9 @@ import {
TYPE_MEMO, TYPE_PROFILER, TYPE_MEMO, TYPE_PROFILER,
TYPE_PROVIDER, TYPE_STRICT_MODE, TYPE_PROVIDER, TYPE_STRICT_MODE,
TYPE_SUSPENSE, TYPE_SUSPENSE,
} from '../utils/elementType'; } from '../../external/JSXElementType';
import { VNode } from './VNode'; import { VNode } from './VNode';
import {HorizonElement} from '../Types'; import {JSXElement} from '../Types';
const typeLazyMap = { const typeLazyMap = {
[TYPE_FORWARD_REF]: ForwardRef, [TYPE_FORWARD_REF]: ForwardRef,
@ -156,7 +156,7 @@ export function updateVNodePath(vNode: VNode) {
vNode.path = [...vNode.parent.path, vNode.cIndex]; vNode.path = [...vNode.parent.path, vNode.cIndex];
} }
export function createVNodeFromElement(element: HorizonElement): VNode { export function createVNodeFromElement(element: JSXElement): VNode {
const type = element.type; const type = element.type;
const key = element.key; const key = element.key;
const props = element.props; const props = element.props;

View File

@ -13,7 +13,7 @@ export function getSiblingVNode(node) {
} }
export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinish?: Function) { export function travelChildren(beginVNode: VNode, handleVNode: Function, isFinish?: Function) {
let node = beginVNode; let node: VNode | null = beginVNode;
while (node !== null) { while (node !== null) {
if (isFinish && isFinish(node)) { if (isFinish && isFinish(node)) {
@ -77,10 +77,6 @@ export function travelVNodeTree(
// 置空vNode // 置空vNode
export function clearVNode(vNode: VNode) { export function clearVNode(vNode: VNode) {
clearOneVNode(vNode);
}
function clearOneVNode(vNode: VNode) {
vNode.child = null; vNode.child = null;
vNode.next = null; vNode.next = null;
vNode.depContexts = []; vNode.depContexts = [];
@ -105,6 +101,8 @@ function clearOneVNode(vNode: VNode) {
vNode.path = []; vNode.path = [];
vNode.toUpdateNodes = null; vNode.toUpdateNodes = null;
vNode.belongClassVNode = null;
} }
// 是dom类型的vNode // 是dom类型的vNode
@ -225,7 +223,7 @@ function isSameContainer(
} }
// 注释类型的节点 // 注释类型的节点
if (isComment(container) && container.parentNode === targetContainer) { if (isComment(container) && container.parentNode === targetContainer) {
return true return true;
} }
return false; return false;
} }