diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts
index 6b9e70f13..c493da22d 100644
--- a/packages/designer/src/document/document-model.ts
+++ b/packages/designer/src/document/document-model.ts
@@ -198,7 +198,7 @@ export class DocumentModel {
* 根据 id 获取节点
*/
getNodeCount(): number {
- return this._nodesMap.size;
+ return this._nodesMap?.size;
}
/**
diff --git a/packages/rax-simulator-renderer/src/renderer-view.tsx b/packages/rax-simulator-renderer/src/renderer-view.tsx
index 711053e80..8444e73ef 100644
--- a/packages/rax-simulator-renderer/src/renderer-view.tsx
+++ b/packages/rax-simulator-renderer/src/renderer-view.tsx
@@ -187,7 +187,7 @@ class Renderer extends Component<{
render() {
const { documentInstance } = this.props;
- const { container } = documentInstance;
+ const { container, document } = documentInstance;
const { designMode, device } = container;
const { rendererContainer: renderer } = this.props;
this.startTime = Date.now();
@@ -209,6 +209,7 @@ class Renderer extends Component<{
onCompGetRef={(schema: any, ref: any) => {
documentInstance.mountInstance(schema.id, ref);
}}
+ documentId={document.id}
getNode={(id: string) => documentInstance.getNode(id) as any}
customCreateElement={(Component: any, props: any, children: any) => {
const { __id, ...viewProps } = props;
diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx
index 3c0978aa3..ec1ebdf4e 100644
--- a/packages/react-simulator-renderer/src/renderer-view.tsx
+++ b/packages/react-simulator-renderer/src/renderer-view.tsx
@@ -154,7 +154,7 @@ class Renderer extends Component<{
render() {
const { documentInstance, rendererContainer: renderer } = this.props;
- const { container } = documentInstance;
+ const { container, document } = documentInstance;
const { designMode, device, locale } = container;
const messages = container.context?.utils?.i18n?.messages || {};
this.startTime = Date.now();
@@ -172,6 +172,7 @@ class Renderer extends Component<{
appHelper={container.context}
designMode={designMode}
device={device}
+ documentId={document.id}
suspended={renderer.suspended}
self={renderer.scope}
getNode={(id: string) => documentInstance.getNode(id) as Node}
diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx
index f40522a58..c6dde182f 100644
--- a/packages/renderer-core/src/hoc/leaf.tsx
+++ b/packages/renderer-core/src/hoc/leaf.tsx
@@ -50,16 +50,30 @@ enum RerenderType {
}
// 缓存 Leaf 层组件,防止重新渲染问题
-const leafComponentCache: {
+let leafComponentCaches: {
[componentName: string]: any;
} = {};
+
+let cacheDocumentId: any;
+
+function clearCaches(curDocumentId: any, {
+ __debug,
+}: any) {
+ if (cacheDocumentId === curDocumentId) {
+ return;
+ }
+ __debug(`DocumentId changed to ${curDocumentId}, clear caches!`);
+ cacheDocumentId = curDocumentId;
+ leafComponentCaches = {};
+}
+
// 缓存导致 rerender 的订阅事件
const rerenderEventCache: {
[componentId: string]: any;
} = {};
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
-function makeRerenderEvent({
+function initRerenderEvent({
schema,
__debug,
container,
@@ -98,6 +112,7 @@ function clearRerenderEvent(id: string): void {
if (!rerenderEventCache[id]) {
rerenderEventCache[id] = {
clear: true,
+ dispose: [],
};
return;
}
@@ -119,27 +134,34 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
} = baseRenderer;
const engine = baseRenderer.context.engine;
const host: BuiltinSimulatorHost = baseRenderer.props.__host;
+ const curDocumentId = baseRenderer.props?.documentId;
const getNode = baseRenderer.props?.getNode;
const container: BuiltinSimulatorHost = baseRenderer.props.__container;
const editor = host?.designer?.editor;
- const { Component } = adapter.getRuntime();
+ const { Component, forwardRef } = adapter.getRuntime();
+
+ if (curDocumentId !== cacheDocumentId) {
+ clearCaches(curDocumentId, {
+ __debug,
+ });
+ }
if (!isReactComponent(Comp)) {
console.error(`${schema.componentName} component may be has errors: `, Comp);
}
- makeRerenderEvent({
+ initRerenderEvent({
schema,
__debug,
container,
getNode,
});
- if (leafComponentCache[schema.componentName]) {
- return leafComponentCache[schema.componentName];
+ if (leafComponentCaches[schema.componentName]) {
+ return leafComponentCaches[schema.componentName];
}
- class LeafWrapper extends Component {
+ class LeafHoc extends Component {
recordInfo: {
startTime?: number | null;
type?: string;
@@ -156,7 +178,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
return;
}
const endTime = Date.now();
- const nodeCount = host.designer.currentDocument?.getNodeCount?.();
+ const nodeCount = host?.designer?.currentDocument?.getNodeCount?.();
const componentName = this.recordInfo.node?.componentName || this.leaf?.componentName || 'UnknownComponent';
editor?.emit(GlobalEvent.Node.Rerender, {
componentName,
@@ -171,18 +193,39 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
this.recordTime();
}
+ componentDidMount() {
+ this.recordTime();
+ }
+
+ get childrenMap(): any {
+ const map = new Map();
+
+ if (!this.hasChildren) {
+ return map;
+ }
+
+ this.children.forEach((d: any) => {
+ if (Array.isArray(d)) {
+ map.set(d[0].props.componentId, d);
+ return;
+ }
+ map.set(d.props.componentId, d);
+ });
+
+ return map;
+ }
+
constructor(props: IProps, context: any) {
super(props, context);
// 监听以下事件,当变化时更新自己
- clearRerenderEvent(schema.id);
+ __debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
+ clearRerenderEvent(this.props.componentId);
this.initOnPropsChangeEvent();
this.initOnChildrenChangeEvent();
this.initOnVisibleChangeEvent();
- __debug(`${schema.componentName}[${schema.id}] leaf render in SimulatorRendererView`);
this.state = {
nodeChildren: null,
childrenInState: false,
- __tag: props.__tag,
};
}
@@ -198,17 +241,11 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
// }
componentWillReceiveProps(nextProps: any) {
- const { _leaf, __tag, children, ...rest } = nextProps;
- if (nextProps.__tag === this.state.__tag) {
- const nextProps = getProps(this.leaf?.export?.(TransformStage.Render) as types.ISchema, Comp, componentInfo);
- this.setState({
- nodeProps: {
- ...rest,
- ...nextProps,
- },
- });
+ const { _leaf } = nextProps;
+ if (nextProps.__tag === this.props.__tag) {
return null;
}
+
if (_leaf && this.leaf && _leaf !== this.leaf) {
this.disposeFunctions.forEach(fn => fn());
this.disposeFunctions = [];
@@ -218,10 +255,9 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
}
this.setState({
- nodeChildren: children,
- nodeProps: rest,
- childrenInState: true,
- __tag,
+ nodeChildren: null,
+ nodeProps: {},
+ childrenInState: false,
});
}
@@ -300,7 +336,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
// }
this.beforeRender(`${RerenderType.ChildChanged}-${type}`, node);
__debug(`${leaf} component trigger onChildrenChange event`);
- const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as types.ISchema, Comp);
+ const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as types.ISchema, Comp, this.childrenMap);
this.setState({
nodeChildren: nextChild,
childrenInState: true,
@@ -359,17 +395,28 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
return null;
}
+ const {
+ ref,
+ ...rest
+ } = this.props;
+
const compProps = {
- ...this.props,
+ ...rest,
...(this.state.nodeProps || {}),
children: [],
__id: this.props.componentId,
+ ref: this.props.forwardedRef,
};
return engine.createElement(Comp, compProps, this.hasChildren ? this.children : null);
}
}
+ const LeafWrapper = forwardRef((props: any, ref: any) => (
+ // @ts-ignore
+
+ ));
+
if (typeof Comp === 'object') {
const compExtraPropertyNames = Object.getOwnPropertyNames(Comp).filter(d => !compDefaultPropertyNames.includes(d));
@@ -382,7 +429,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
LeafWrapper.displayName = (Comp as any).displayName;
- leafComponentCache[schema.componentName] = LeafWrapper;
+ leafComponentCaches[schema.componentName] = LeafWrapper;
return LeafWrapper;
}
\ No newline at end of file
diff --git a/packages/renderer-core/src/renderer/addon.tsx b/packages/renderer-core/src/renderer/addon.tsx
index cedb3e065..7720051a4 100644
--- a/packages/renderer-core/src/renderer/addon.tsx
+++ b/packages/renderer-core/src/renderer/addon.tsx
@@ -77,7 +77,7 @@ export default function addonRendererFactory() {
return '插件 schema 结构异常!';
}
- this.__debug(`render - ${__schema.fileName}`);
+ this.__debug(`${AddonRenderer.dislayName} render - ${__schema.fileName}`);
this.__generateCtx({
component: this,
});
diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx
index 87f4ad919..f234677ac 100644
--- a/packages/renderer-core/src/renderer/base.tsx
+++ b/packages/renderer-core/src/renderer/base.tsx
@@ -521,7 +521,7 @@ export default function baseRenererFactory() {
props.key = props.__id;
}
- let child: any = this.__getSchemaChildrenVirtualDom(schema, Comp);
+ let child: any = parentInfo.componentChildren || this.__getSchemaChildrenVirtualDom(schema, Comp);
const renderComp = (props: any) => engine.createElement(Comp, props, child);
// 设计模式下的特殊处理
if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) {
@@ -580,7 +580,7 @@ export default function baseRenererFactory() {
.map((d: IComponentHoc) => d.hoc);
}
- __getSchemaChildrenVirtualDom = (schema: ISchema, Comp: any) => {
+ __getSchemaChildrenVirtualDom = (schema: ISchema, Comp: any, childrenMap?: Map) => {
let _children = this.getSchemaChildren(schema);
let children: any = [];
@@ -596,6 +596,8 @@ export default function baseRenererFactory() {
{
schema,
Comp,
+ // 有 childrenMap 情况下,children 只计算第一层,不需要遍历多层。
+ componentChildren: childrenMap?.get(_child.id)?.props.children || null,
},
);
@@ -834,11 +836,16 @@ export default function baseRenererFactory() {
componentInfo: {},
});
const { className } = data;
+ const otherProps: any = {};
const { engine } = this.context || {};
if (!engine) {
return null;
}
+ if (this._designModeIsDesign) {
+ otherProps.__tag = Math.random();
+ }
+
const child = engine.createElement(
Comp,
{
@@ -847,6 +854,7 @@ export default function baseRenererFactory() {
ref: this.__getRef,
className: classnames(getFileCssName(__schema?.fileName), className, this.props.className),
__id: __schema?.id,
+ ...otherProps,
},
this.__createDom(),
);
diff --git a/packages/renderer-core/src/renderer/block.tsx b/packages/renderer-core/src/renderer/block.tsx
index 599410c4d..d6d230c4d 100644
--- a/packages/renderer-core/src/renderer/block.tsx
+++ b/packages/renderer-core/src/renderer/block.tsx
@@ -23,7 +23,7 @@ export default function blockRendererFactory() {
return '区块 schema 结构异常!';
}
- this.__debug(`render - ${__schema.fileName}`);
+ this.__debug(`${BlockRenderer.dislayName} render - ${__schema.fileName}`);
this.__generateCtx({});
this.__render();
diff --git a/packages/renderer-core/src/renderer/component.tsx b/packages/renderer-core/src/renderer/component.tsx
index 229958f46..81b40dc32 100644
--- a/packages/renderer-core/src/renderer/component.tsx
+++ b/packages/renderer-core/src/renderer/component.tsx
@@ -23,7 +23,7 @@ export default function componentRendererFactory() {
if (this.__checkSchema(__schema)) {
return '自定义组件 schema 结构异常!';
}
- this.__debug(`render - ${__schema.fileName}`);
+ this.__debug(`${CompRenderer.dislayName} render - ${__schema.fileName}`);
this.__generateCtx({
component: this,
diff --git a/packages/renderer-core/src/renderer/page.tsx b/packages/renderer-core/src/renderer/page.tsx
index 3c7be518f..6e7f290ed 100644
--- a/packages/renderer-core/src/renderer/page.tsx
+++ b/packages/renderer-core/src/renderer/page.tsx
@@ -36,7 +36,7 @@ export default function pageRendererFactory() {
if (this.__checkSchema(__schema)) {
return '页面schema结构异常!';
}
- this.__debug(`render - ${__schema.fileName}`);
+ this.__debug(`${PageRenderer.dislayName} render - ${__schema.fileName}`);
this.__bindCustomMethods(this.props);
this.__initDataSource(this.props);
diff --git a/packages/renderer-core/src/renderer/temp.tsx b/packages/renderer-core/src/renderer/temp.tsx
index fc3e3c48d..061e561b2 100644
--- a/packages/renderer-core/src/renderer/temp.tsx
+++ b/packages/renderer-core/src/renderer/temp.tsx
@@ -48,7 +48,7 @@ export default function tempRendererFactory() {
return '下钻编辑 schema 结构异常!';
}
- this.__debug(`render - ${__schema.fileName}`);
+ this.__debug(`${TempRenderer.dislayName} render - ${__schema.fileName}`);
return this.__renderContent(this.__renderContextProvider({ __ctx }));
}
diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts
index e5e68cf3b..e1246082a 100644
--- a/packages/renderer-core/src/types/index.ts
+++ b/packages/renderer-core/src/types/index.ts
@@ -63,6 +63,7 @@ export interface IInfo {
schema: ISchema;
Comp: any;
componentInfo?: any;
+ componentChildren?: any
}
export interface JSExpression {