mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-11-27 08:39:59 +08:00
add HiddenImplWrapper
This commit is contained in:
parent
869937dfbd
commit
0da51400bc
@ -0,0 +1,43 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { ImplWrapperProps, TraitResult } from '../../../types';
|
||||
import { ImplWrapperMain } from './ImplWrapperMain';
|
||||
import { useRuntimeFunctions } from './hooks/useRuntimeFunctions';
|
||||
|
||||
export const HiddenImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
|
||||
(props, ref) => {
|
||||
const { component: c, services } = props;
|
||||
const { stateManager } = services;
|
||||
const { executeTrait } = useRuntimeFunctions(props);
|
||||
const hiddenTraits = useMemo(
|
||||
() => c.traits.filter(t => t.type === 'core/v1/hidden'),
|
||||
[c.traits]
|
||||
);
|
||||
const [isHidden, setIsHidden] = useState(() => {
|
||||
const results: TraitResult<string, string>[] = hiddenTraits.map(t => {
|
||||
const properties = stateManager.deepEval(t.properties);
|
||||
return executeTrait(t, properties);
|
||||
});
|
||||
return results.some(result => result.unmount);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (hiddenTraits.length > 0) {
|
||||
hiddenTraits.map(t => {
|
||||
const properties = stateManager.deepEvalAndWatch(t.properties, newV => {
|
||||
console.log('get hidden results', newV.result.hidden);
|
||||
const result = executeTrait(t, newV.result);
|
||||
setIsHidden(!!result.unmount);
|
||||
if (result.unmount) {
|
||||
// // Every component's state is initialize in initStateAnd Method.
|
||||
// // So if if it should not render, we should remove it from store.
|
||||
delete stateManager.store[c.id];
|
||||
}
|
||||
});
|
||||
return executeTrait(t, properties);
|
||||
});
|
||||
}
|
||||
}, [c, executeTrait, hiddenTraits, stateManager]);
|
||||
|
||||
return !isHidden ? <ImplWrapperMain {...props} ref={ref} /> : null;
|
||||
}
|
||||
);
|
@ -2,6 +2,17 @@ import React from 'react';
|
||||
import { ImplWrapperProps } from '../../../types';
|
||||
import { shallowCompareArray } from '../../../utils/shallowCompareArray';
|
||||
import { ImplWrapperMain } from './ImplWrapperMain';
|
||||
// import { HiddenImplWrapper } from './HiddenImplWrapper';
|
||||
|
||||
// export const _ImplWrapper = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
|
||||
// (props, ref) => {
|
||||
// return (
|
||||
// <HiddenImplWrapper {...props}>
|
||||
// <ImplWrapperMain {...props} ref={ref} />
|
||||
// </HiddenImplWrapper>
|
||||
// );
|
||||
// }
|
||||
// );
|
||||
|
||||
export const ImplWrapper = React.memo<ImplWrapperProps>(
|
||||
ImplWrapperMain,
|
||||
|
@ -12,6 +12,7 @@ import { useGridLayout } from './hooks/useGridLayout';
|
||||
export const ImplWrapperMain = React.forwardRef<HTMLDivElement, ImplWrapperProps>(
|
||||
(props, ref) => {
|
||||
const { component: c, children } = props;
|
||||
console.info('####ImplWrapper Render', c.id);
|
||||
const { registry, stateManager } = props.services;
|
||||
|
||||
const Impl = registry.getComponent(c.parsedType.version, c.parsedType.name).impl;
|
||||
@ -36,12 +37,14 @@ export const ImplWrapperMain = React.forwardRef<HTMLDivElement, ImplWrapperProps
|
||||
|
||||
// eval traits' properties then execute traits
|
||||
useEffect(() => {
|
||||
console.log('开始监听 trait 表达式变化', c.id);
|
||||
const stops: ReturnType<typeof watch>[] = [];
|
||||
const properties: Array<RuntimeTraitSchema['properties']> = [];
|
||||
c.traits.forEach((t, i) => {
|
||||
const { result, stop } = stateManager.deepEvalAndWatch(
|
||||
t.properties,
|
||||
({ result: property }: any) => {
|
||||
console.log('trait变了', t.type, property);
|
||||
const traitResult = executeTrait(t, property);
|
||||
setTraitResults(oldResults => {
|
||||
// assume traits number and order will not change
|
||||
@ -101,6 +104,7 @@ export const ImplWrapperMain = React.forwardRef<HTMLDivElement, ImplWrapperProps
|
||||
}, [c.properties, stateManager]);
|
||||
|
||||
useEffect(() => {
|
||||
console.info('####Component DidMount', c.id);
|
||||
const clearFunctions = propsFromTraits?.componentDidMount?.map(e => e());
|
||||
return () => {
|
||||
clearFunctions?.forEach(func => func && func());
|
||||
@ -109,6 +113,7 @@ export const ImplWrapperMain = React.forwardRef<HTMLDivElement, ImplWrapperProps
|
||||
}, []);
|
||||
|
||||
useDidUpdate(() => {
|
||||
console.info('####Component Update', c.id);
|
||||
const clearFunctions = propsFromTraits?.componentDidUpdate?.map(e => e());
|
||||
return () => {
|
||||
clearFunctions?.forEach(func => func && func());
|
||||
@ -116,6 +121,11 @@ export const ImplWrapperMain = React.forwardRef<HTMLDivElement, ImplWrapperProps
|
||||
});
|
||||
|
||||
useDidUnmount(() => {
|
||||
console.info(
|
||||
'####Component DidUnmount',
|
||||
c.id,
|
||||
propsFromTraits?.componentDidUnmount
|
||||
);
|
||||
propsFromTraits?.componentDidUnmount?.forEach(e => e());
|
||||
});
|
||||
|
||||
|
@ -15,11 +15,13 @@ export function useEleRef(props: ImplWrapperProps) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.info('####ImplWrapper DidMount', c.id);
|
||||
// If a component is in module, it should not have mask, so we needn't set it
|
||||
if (eleRef.current && !isInModule) {
|
||||
eleMap.set(c.id, eleRef.current);
|
||||
}
|
||||
return () => {
|
||||
console.info('####ImplWrapper DidUnmount', c.id);
|
||||
if (!isInModule) {
|
||||
eleMap.delete(c.id);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ export function useRuntimeFunctions(props: ImplWrapperProps) {
|
||||
|
||||
const executeTrait = useCallback(
|
||||
(trait: RuntimeTraitSchema, traitProperty: RuntimeTraitSchema['properties']) => {
|
||||
console.log('执行了trait', trait.type);
|
||||
const tImpl = registry.getTrait(
|
||||
trait.parsedType.version,
|
||||
trait.parsedType.name
|
||||
|
@ -37,6 +37,34 @@ export default implementRuntimeComponent({
|
||||
styleSlots: ['content'],
|
||||
events: [],
|
||||
},
|
||||
})(({ value, customStyle, elementRef }) => {
|
||||
return <_Text value={value} cssStyle={customStyle?.content} ref={elementRef} />;
|
||||
});
|
||||
})(
|
||||
({
|
||||
value,
|
||||
customStyle,
|
||||
elementRef,
|
||||
// component,
|
||||
// componentDidMount,
|
||||
// componentDidUnmount,
|
||||
// componentDidUpdate,
|
||||
}) => {
|
||||
// console.info('####Component Render', component.id);
|
||||
// useEffect(() => {
|
||||
// console.info('####Component DidMount', component.id);
|
||||
// componentDidMount?.forEach(e => e());
|
||||
// }, [component.id, componentDidMount]);
|
||||
// useEffect(() => {
|
||||
// console.info('####Component Update', component.id);
|
||||
// componentDidUpdate?.forEach(e => e());
|
||||
// }, [component.id, componentDidMount, componentDidUpdate]);
|
||||
// useEffect(() => {
|
||||
// return () => {
|
||||
// console.info('Component DidUnmount', component.id, componentDidUnmount);
|
||||
// componentDidUnmount?.forEach(e => e());
|
||||
// };
|
||||
// }, [component.id, componentDidUnmount]);
|
||||
return <_Text value={value} cssStyle={customStyle?.content} ref={elementRef} />;
|
||||
}
|
||||
);
|
||||
|
||||
// 不知道为什么,计时器还在继续,貌似是因为style执行了两次,两个interval,但是clear只执行了一次
|
||||
// 另一个问题是,为什么style会执行两次呢?
|
||||
|
@ -28,6 +28,7 @@ const FetchTraitFactory: TraitImplFactory<Static<typeof FetchTraitPropertiesSpec
|
||||
const lazy = _lazy === undefined ? true : _lazy;
|
||||
|
||||
const fetchData = () => {
|
||||
console.log('fetch body', body);
|
||||
if (disabled) return;
|
||||
// TODO: clear when component destroy
|
||||
// FIXME: listen to the header change
|
||||
|
@ -28,6 +28,7 @@ const StateTraitFactory: TraitImplFactory<Static<typeof PropsSpec>> = () => {
|
||||
props: {
|
||||
componentDidMount: [
|
||||
() => {
|
||||
console.log('merge state');
|
||||
mergeState({ [key]: initialValue });
|
||||
},
|
||||
],
|
||||
|
@ -8,9 +8,31 @@ const StyleTraitFactory: TraitImplFactory<Static<typeof PropsSpec>> = () => {
|
||||
styles.forEach(style => {
|
||||
customStyle[style.styleSlot] = style.style;
|
||||
});
|
||||
let interval: ReturnType<typeof setInterval> | undefined;
|
||||
return {
|
||||
props: {
|
||||
customStyle,
|
||||
componentDidMount: [
|
||||
() => {
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
interval = setInterval(() => {
|
||||
console.log(2333, customStyle.content);
|
||||
}, 1000);
|
||||
console.log('开始计时', interval);
|
||||
},
|
||||
],
|
||||
componentDidUpdate: [],
|
||||
componentDidUnmount: [
|
||||
() => {
|
||||
console.log('停止计时', interval);
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
interval = undefined;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user