Merge branch refactor/leafVisible into feat/0.16.14

Title: fix: _leaf 不存在在 props 上时,撤回之后无法修改其属性 

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/6677960
This commit is contained in:
lihao.ylh 2021-10-15 17:33:51 +08:00
commit a6d4747e20
5 changed files with 114 additions and 61 deletions

View File

@ -185,12 +185,23 @@ class Renderer extends Component<{
} }
} }
schemaChangedSymbol = false;
getSchemaChangedSymbol = () => {
return this.schemaChangedSymbol;
};
setSchemaChangedSymbol = (symbol: boolean) => {
this.schemaChangedSymbol = symbol;
};
render() { render() {
const { documentInstance } = this.props; const { documentInstance } = this.props;
const { container, document } = documentInstance; const { container, document } = documentInstance;
const { designMode, device } = container; const { designMode, device } = container;
const { rendererContainer: renderer } = this.props; const { rendererContainer: renderer } = this.props;
this.startTime = Date.now(); this.startTime = Date.now();
this.schemaChangedSymbol = false;
return ( return (
// @ts-ignore // @ts-ignore

View File

@ -152,12 +152,23 @@ class Renderer extends Component<{
this.recordTime(); this.recordTime();
} }
schemaChangedSymbol = false;
getSchemaChangedSymbol = () => {
return this.schemaChangedSymbol;
};
setSchemaChangedSymbol = (symbol: boolean) => {
this.schemaChangedSymbol = symbol;
};
render() { render() {
const { documentInstance, rendererContainer: renderer } = this.props; const { documentInstance, rendererContainer: renderer } = this.props;
const { container, document } = documentInstance; const { container, document } = documentInstance;
const { designMode, device, locale } = container; const { designMode, device, locale } = container;
const messages = container.context?.utils?.i18n?.messages || {}; const messages = container.context?.utils?.i18n?.messages || {};
this.startTime = Date.now(); this.startTime = Date.now();
this.schemaChangedSymbol = false;
if (!container.autoRender) return null; if (!container.autoRender) return null;
return ( return (
@ -175,6 +186,8 @@ class Renderer extends Component<{
documentId={document.id} documentId={document.id}
suspended={renderer.suspended} suspended={renderer.suspended}
self={renderer.scope} self={renderer.scope}
getSchemaChangedSymbol={this.getSchemaChangedSymbol}
setSchemaChangedSymbol={this.setSchemaChangedSymbol}
getNode={(id: string) => documentInstance.getNode(id) as Node} getNode={(id: string) => documentInstance.getNode(id) as Node}
rendererName="PageRenderer" rendererName="PageRenderer"
customCreateElement={(Component: any, props: any, children: any) => { customCreateElement={(Component: any, props: any, children: any) => {

View File

@ -45,32 +45,27 @@ enum RerenderType {
ChildChanged = 'ChildChanged', ChildChanged = 'ChildChanged',
PropsChanged = 'PropsChanged', PropsChanged = 'PropsChanged',
VisibleChanged = 'VisibleChanged', VisibleChanged = 'VisibleChanged',
LangChanged = 'LangChanged',
I18nChanged = 'I18nChanged',
} }
// 缓存 Leaf 层组件,防止重新渲染问题 // 缓存 Leaf 层组件,防止重新渲染问题
let leafComponentCaches: { class LeafCache {
[componentName: string]: any; constructor(public documentId: string) {
} = {};
let cacheDocumentId: any;
function clearCaches(curDocumentId: any, {
__debug,
}: any) {
if (cacheDocumentId === curDocumentId) {
return;
} }
__debug(`DocumentId changed to ${curDocumentId}, clear caches!`); /** 组件缓存 */
cacheDocumentId = curDocumentId; component = new Map();
leafComponentCaches = {};
/**
* state
*/
state = new Map();
/**
* rerender
*/
event = new Map();
} }
// 缓存导致 rerender 的订阅事件 let cache: LeafCache;
const rerenderEventCache: {
[componentId: string]: any;
} = {};
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */ /** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
function initRerenderEvent({ function initRerenderEvent({
@ -81,13 +76,13 @@ function initRerenderEvent({
}: any) { }: any) {
const leaf = getNode?.(schema.id); const leaf = getNode?.(schema.id);
if (!leaf if (!leaf
|| rerenderEventCache[schema.id]?.clear || cache.event.get(schema.id)?.clear
|| leaf === rerenderEventCache[schema.id]?.leaf || leaf === cache.event.get(schema.id)
) { ) {
return; return;
} }
rerenderEventCache[schema.id]?.dispose.forEach((d: any) => d && d()); cache.event.get(schema.id)?.dispose.forEach((d: any) => d && d());
rerenderEventCache[schema.id] = { cache.event.set(schema.id, {
clear: false, clear: false,
leaf, leaf,
dispose: [ dispose: [
@ -104,21 +99,19 @@ function initRerenderEvent({
container.rerender(); container.rerender();
}), }),
], ],
}; });
} }
/** 渲染的 node 节点全局注册事件清除 */ /** 渲染的 node 节点全局注册事件清除 */
function clearRerenderEvent(id: string): void { function clearRerenderEvent(id: string): void {
if (!rerenderEventCache[id]) { if (cache.event.get(id)?.clear) {
rerenderEventCache[id] = {
clear: true,
dispose: [],
};
return; return;
} }
rerenderEventCache[id].dispose.forEach((d: any) => d && d()); cache.event.get(id)?.dispose?.forEach((d: any) => d && d());
rerenderEventCache[id].dispose = []; cache.event.set(id, {
rerenderEventCache[id].clear = true; clear: true,
dispose: [],
});
} }
// 给每个组件包裹一个 HOC Leaf支持组件内部属性变化自响应渲染 // 给每个组件包裹一个 HOC Leaf支持组件内部属性变化自响应渲染
@ -137,13 +130,12 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
const curDocumentId = baseRenderer.props?.documentId; const curDocumentId = baseRenderer.props?.documentId;
const getNode = baseRenderer.props?.getNode; const getNode = baseRenderer.props?.getNode;
const container: BuiltinSimulatorHost = baseRenderer.props.__container; const container: BuiltinSimulatorHost = baseRenderer.props.__container;
const setSchemaChangedSymbol = baseRenderer.props?.setSchemaChangedSymbol;
const editor = host?.designer?.editor; const editor = host?.designer?.editor;
const { Component, forwardRef } = adapter.getRuntime(); const { Component, forwardRef } = adapter.getRuntime();
if (curDocumentId !== cacheDocumentId) { if (!cache || curDocumentId !== cache.documentId) {
clearCaches(curDocumentId, { cache = new LeafCache(curDocumentId);
__debug,
});
} }
if (!isReactComponent(Comp)) { if (!isReactComponent(Comp)) {
@ -157,8 +149,8 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
getNode, getNode,
}); });
if (leafComponentCaches[schema.componentName]) { if (cache.component.has(schema.componentName)) {
return leafComponentCaches[schema.componentName]; return cache.component.get(schema.componentName);
} }
class LeafHoc extends Component { class LeafHoc extends Component {
@ -215,18 +207,45 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
return map; return map;
} }
get defaultState() {
const {
hidden = false,
} = this.leaf?.schema || {};
return {
nodeChildren: null,
childrenInState: false,
visible: !hidden,
};
}
constructor(props: IProps, context: any) { constructor(props: IProps, context: any) {
super(props, context); super(props, context);
// 监听以下事件,当变化时更新自己 // 监听以下事件,当变化时更新自己
__debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`); __debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
clearRerenderEvent(this.props.componentId); clearRerenderEvent(this.props.componentId);
this.initOnPropsChangeEvent(); const _leaf = this.leaf;
this.initOnChildrenChangeEvent(); this.initOnPropsChangeEvent(_leaf);
this.initOnVisibleChangeEvent(); this.initOnChildrenChangeEvent(_leaf);
this.state = { this.initOnVisibleChangeEvent(_leaf);
nodeChildren: null, this.curEventLeaf = _leaf;
childrenInState: false,
}; let cacheState = cache.state.get(props.componentId);
if (!cacheState || cacheState.__tag !== props.__tag) {
cacheState = this.defaultState;
}
this.state = cacheState;
}
private curEventLeaf;
setState(state: any) {
cache.state.set(this.props.componentId, {
...this.state,
...state,
__tag: this.props.__tag,
});
super.setState(state);
} }
/** 由于内部属性变化,在触发渲染前,会执行该函数 */ /** 由于内部属性变化,在触发渲染前,会执行该函数 */
@ -234,6 +253,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
this.recordInfo.startTime = Date.now(); this.recordInfo.startTime = Date.now();
this.recordInfo.type = type; this.recordInfo.type = type;
this.recordInfo.node = node; this.recordInfo.node = node;
setSchemaChangedSymbol?.(true);
} }
// get isInWhitelist() { // get isInWhitelist() {
@ -241,17 +261,19 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
// } // }
componentWillReceiveProps(nextProps: any) { componentWillReceiveProps(nextProps: any) {
const { _leaf } = nextProps; let { _leaf, componentId } = nextProps;
if (nextProps.__tag === this.props.__tag) { if (nextProps.__tag === this.props.__tag) {
return null; return null;
} }
if (_leaf && this.leaf && _leaf !== this.leaf) { _leaf = _leaf || getNode(componentId);
if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) {
this.disposeFunctions.forEach(fn => fn()); this.disposeFunctions.forEach(fn => fn());
this.disposeFunctions = []; this.disposeFunctions = [];
this.initOnChildrenChangeEvent(_leaf); this.initOnChildrenChangeEvent(_leaf);
this.initOnPropsChangeEvent(_leaf); this.initOnPropsChangeEvent(_leaf);
this.initOnVisibleChangeEvent(_leaf); this.initOnVisibleChangeEvent(_leaf);
this.curEventLeaf = _leaf;
} }
this.setState({ this.setState({
@ -261,7 +283,6 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
}); });
} }
/** 监听参数变化 */ /** 监听参数变化 */
initOnPropsChangeEvent(leaf = this.leaf): void { initOnPropsChangeEvent(leaf = this.leaf): void {
const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => { const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => {
@ -383,18 +404,8 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
return this.props._leaf || getNode(this.props.componentId); return this.props._leaf || getNode(this.props.componentId);
} }
get visible(): boolean {
if (typeof this.state.visible === 'boolean') {
return this.state.visible;
}
if (typeof this.leaf?.schema?.hidden === 'boolean') {
return !this.leaf?.schema?.hidden;
}
return true;
}
render() { render() {
if (!this.visible) { if (!this.state.visible) {
return null; return null;
} }
@ -432,7 +443,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
LeafWrapper.displayName = (Comp as any).displayName; LeafWrapper.displayName = (Comp as any).displayName;
leafComponentCaches[schema.componentName] = LeafWrapper; cache.component.set(schema.componentName, LeafWrapper);
return LeafWrapper; return LeafWrapper;
} }

View File

@ -148,6 +148,20 @@ export default function baseRenererFactory() {
}); });
}); });
shouldComponentUpdate() {
if (this.props.getSchemaChangedSymbol?.() && this.props.__container?.rerender) {
this.props.__container?.rerender();
return false;
}
return true;
}
forceUpdate() {
if (this.shouldComponentUpdate()) {
super.forceUpdate();
}
}
__setLifeCycleMethods = (method: string, args?: any) => { __setLifeCycleMethods = (method: string, args?: any) => {
const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {}); const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {});
let fn = lifeCycleMethods[method]; let fn = lifeCycleMethods[method];

View File

@ -16,6 +16,10 @@ export interface IProps {
suspended?: boolean; suspended?: boolean;
onCompGetRef?: (schema: ISchema, ref: any) => void; onCompGetRef?: (schema: ISchema, ref: any) => void;
onCompGetCtx?: (schema: ISchema, ref: any) => void; onCompGetCtx?: (schema: ISchema, ref: any) => void;
/** 传入的 schema 是否有变更 */
getSchemaChangedSymbol: () => boolean;
/** 设置 schema 是否有变更 */
setSchemaChangedSymbol: (symbol: boolean) => void;
customCreateElement?: (...args: any) => any; customCreateElement?: (...args: any) => any;
rendererName: string; rendererName: string;
notFoundComponent?: any; notFoundComponent?: any;