Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added memoization to minimize re-rendering #1159

Merged
merged 9 commits into from
Sep 12, 2024
10 changes: 5 additions & 5 deletions client/packages/lowcoder/src/comps/comps/gridItemComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const TmpComp = withTypeAndChildren<
childrenMap
);

function CachedView(props: { comp: Comp; name: string }) {
const CachedView = React.memo((props: { comp: Comp; name: string }) => {
return React.useMemo(
() => (
<Profiler id={props.name} onRender={profilerCallback}>
Expand All @@ -73,13 +73,13 @@ function CachedView(props: { comp: Comp; name: string }) {
),
[props.comp, props.name]
);
}
})

function CachedPropertyView(props: {
const CachedPropertyView = React.memo((props: {
comp: Comp;
name: string;
withParamsContext: WithParamsContext;
}) {
}) => {
const prevHints = useContext(CompExposingContext);
const { withParamsContext } = props;
const hints = useMemo(
Expand Down Expand Up @@ -109,7 +109,7 @@ function CachedPropertyView(props: {
</>
);
}, [props.comp, props.name, hints, searchText, setSearchText]);
}
});

export class GridItemComp extends TmpComp {
private readonly withParamsContext: WithParamsContext = { params: {} };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import styled from "styled-components";
import { RemoteCompInfo } from "types/remoteComp";
import { withErrorBoundary } from "comps/generators/withErrorBoundary";
import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext";
import React from "react";

const ViewError = styled.div`
display: flex;
Expand Down Expand Up @@ -50,7 +51,7 @@ interface LazyCompViewProps {
errorElement?: (error: any) => React.ReactNode;
}

function LazyCompView(props: React.PropsWithChildren<LazyCompViewProps>) {
const LazyCompView = React.memo((props: React.PropsWithChildren<LazyCompViewProps>) => {
const { loadComp, loadingElement, errorElement } = props;
const [error, setError] = useState<any>("");
const currentTheme = useContext(ThemeContext)?.theme;
Expand Down Expand Up @@ -83,7 +84,7 @@ function LazyCompView(props: React.PropsWithChildren<LazyCompViewProps>) {
return (
<WhiteLoading />
);
}
});

export type LazyloadCompLoader<T = RemoteCompInfo> = () => Promise<CompConstructor | null>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { loaders } from "./loaders";
import { withErrorBoundary } from "comps/generators/withErrorBoundary";
import { EditorContext } from "@lowcoder-ee/comps/editorState";
import { CompContext } from "@lowcoder-ee/comps/utils/compContext";
import React from "react";

const ViewError = styled.div`
display: flex;
Expand Down Expand Up @@ -53,7 +54,7 @@ interface RemoteCompViewProps {
errorElement?: (error: any) => React.ReactNode;
}

function RemoteCompView(props: React.PropsWithChildren<RemoteCompViewProps>) {
const RemoteCompView = React.memo((props: React.PropsWithChildren<RemoteCompViewProps>) => {
const { loadComp, loadingElement, errorElement, isLowcoderComp } = props;
const [error, setError] = useState<any>("");
const editorState = useContext(EditorContext);
Expand Down Expand Up @@ -93,11 +94,9 @@ function RemoteCompView(props: React.PropsWithChildren<RemoteCompViewProps>) {
}

return (
<ViewLoadingWrapper>
<WhiteLoading />
</ViewLoadingWrapper>
<WhiteLoading />
);
}
});

export function remoteComp<T extends RemoteCompInfo = RemoteCompInfo>(
remoteInfo?: T,
Expand Down
161 changes: 86 additions & 75 deletions client/packages/lowcoder/src/comps/comps/textComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import { PaddingControl } from "../controls/paddingControl";
import React, { useContext, useEffect } from "react";
import { EditorContext } from "comps/editorState";
import { clickEvent, eventHandlerControl } from "../controls/eventHandlerControl";
import { NewChildren } from "../generators/uiCompBuilder";
import { RecordConstructorToComp } from "lowcoder-core";
import { ToViewReturn } from "../generators/multi";

const EventOptions = [clickEvent] as const;

Expand Down Expand Up @@ -130,87 +133,95 @@ const VerticalAlignmentOptions = [
{ label: <AlignVerticalCenter />, value: "center" },
{ label: <AlignBottom />, value: "flex-end" },
] as const;
const childrenMap = {
text: stringExposingStateControl(
"text",
trans("textShow.text", { name: "{{currentUser.name}}" })
),
onEvent: eventHandlerControl(EventOptions),
autoHeight: AutoHeightControl,
type: dropdownControl(typeOptions, "markdown"),
horizontalAlignment: alignWithJustifyControl(),
verticalAlignment: dropdownControl(VerticalAlignmentOptions, "center"),
style: styleControl(TextStyle, 'style'),
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
margin: MarginControl,
padding: PaddingControl,
};

let TextTmpComp = (function () {
const childrenMap = {
text: stringExposingStateControl(
"text",
trans("textShow.text", { name: "{{currentUser.name}}" })
),
onEvent: eventHandlerControl(EventOptions),
autoHeight: AutoHeightControl,
type: dropdownControl(typeOptions, "markdown"),
horizontalAlignment: alignWithJustifyControl(),
verticalAlignment: dropdownControl(VerticalAlignmentOptions, "center"),
style: styleControl(TextStyle, 'style'),
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
margin: MarginControl,
padding: PaddingControl,
};
return new UICompBuilder(childrenMap, (props, dispatch) => {
const value = props.text.value;

return (
<TextContainer
$animationStyle={props.animationStyle}
$type={props.type}
$styleConfig={props.style}
style={{
justifyContent: props.horizontalAlignment,
alignItems: props.autoHeight ? "center" : props.verticalAlignment,
textAlign: props.horizontalAlignment,
rotate: props.style.rotation
}}
onClick={() => props.onEvent("click")}
>
{props.type === "markdown" ? <TacoMarkDown>{value}</TacoMarkDown> : value}
</TextContainer>
);
})
.setPropertyViewFn((children) => {
return (
type ChildrenType = NewChildren<RecordConstructorToComp<typeof childrenMap>>;

const TextPropertyView = React.memo((props: {
children: ChildrenType
}) => {
return (
<>
<Section name={sectionNames.basic}>
{props.children.type.propertyView({
label: trans("value"),
tooltip: trans("textShow.valueTooltip"),
radioButton: true,
})}
{props.children.text.propertyView({})}
</Section>

{["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
<Section name={sectionNames.interaction}>
{hiddenPropertyView(props.children)}
{props.children.onEvent.getPropertyView()}
</Section>
)}

{["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
<>
<Section name={sectionNames.basic}>
{children.type.propertyView({
label: trans("value"),
tooltip: trans("textShow.valueTooltip"),
<Section name={sectionNames.layout}>
{props.children.autoHeight.getPropertyView()}
{!props.children.autoHeight.getView() &&
props.children.verticalAlignment.propertyView({
label: trans("textShow.verticalAlignment"),
radioButton: true,
})}
{props.children.horizontalAlignment.propertyView({
label: trans("textShow.horizontalAlignment"),
radioButton: true,
})}
{children.text.propertyView({})}
</Section>

{["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
<Section name={sectionNames.interaction}>
{hiddenPropertyView(children)}
{children.onEvent.getPropertyView()}
</Section>
)}

{["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
<>
<Section name={sectionNames.layout}>
{children.autoHeight.getPropertyView()}
{!children.autoHeight.getView() &&
children.verticalAlignment.propertyView({
label: trans("textShow.verticalAlignment"),
radioButton: true,
})}
{children.horizontalAlignment.propertyView({
label: trans("textShow.horizontalAlignment"),
radioButton: true,
})}
</Section>
<Section name={sectionNames.style}>
{children.style.getPropertyView()}
</Section>
<Section name={sectionNames.animationStyle} hasTooltip={true}>
{children.animationStyle.getPropertyView()}
</Section>
</>
)}
<Section name={sectionNames.style}>
{props.children.style.getPropertyView()}
</Section>
<Section name={sectionNames.animationStyle} hasTooltip={true}>
{props.children.animationStyle.getPropertyView()}
</Section>
</>
);
})
)}
</>
);
})

const TextView = React.memo((props: ToViewReturn<ChildrenType>) => {
const value = props.text.value;

return (
<TextContainer
$animationStyle={props.animationStyle}
$type={props.type}
$styleConfig={props.style}
style={{
justifyContent: props.horizontalAlignment,
alignItems: props.autoHeight ? "center" : props.verticalAlignment,
textAlign: props.horizontalAlignment,
rotate: props.style.rotation
}}
onClick={() => props.onEvent("click")}
>
{props.type === "markdown" ? <TacoMarkDown>{value}</TacoMarkDown> : value}
</TextContainer>
);
}, (prev, next) => JSON.stringify(prev) === JSON.stringify(next));

let TextTmpComp = (function () {
return new UICompBuilder(childrenMap, (props) => <TextView {...props} />)
.setPropertyViewFn((children) => <TextPropertyView children={children} />)
.build();
})();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export function optionsControl<T extends OptionsControlType>(
uniqField?: keyof ConstructorToView<T>;
// manual mode list title
title?: string;
autoIncField?: keyof PickNumberFields<ConstructorToView<T>>;
}
) {
type OptionViewType = ConstructorToView<T>;
Expand All @@ -369,6 +370,7 @@ export function optionsControl<T extends OptionsControlType>(
manual: manualOptionsControl(VariantComp, {
initOptions: config.initOptions,
uniqField: config.uniqField,
autoIncField: config.autoIncField,
}),
mapData: mapOptionsControl(VariantComp, config.uniqField),
},
Expand Down
17 changes: 10 additions & 7 deletions client/packages/lowcoder/src/comps/controls/slotControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { createContext, useContext } from "react";
import styled from "styled-components";
import { NameGenerator } from "comps/utils";
import { JSONValue } from "util/jsonTypes";
import React from "react";
import { isEqual } from "lodash";

const ModalStyled = styled.div<{ $background?: string }>`
.ant-modal-content {
Expand All @@ -42,23 +44,23 @@ export const SlotConfigContext = createContext<{
modalWidth: 520,
});

const ContainerView = (props: ContainerBaseProps) => {
const ContainerView = React.memo((props: ContainerBaseProps) => {
return <InnerGrid {...props} emptyRows={15} autoHeight />;
};
});

function ModalConfigView(props: {
const ModalConfigView = React.memo((props: {
visible: boolean;
containerProps: ConstructorToView<typeof SimpleContainerComp>;
onCancel: () => void;
}) {
}) => {
const { visible, containerProps, onCancel } = props;
const background = useContext(BackgroundColorContext);
const { modalWidth = 520 } = useContext(SlotConfigContext);
if (!visible) {
return null;
}
return (
(<ModalWrapper>
<ModalWrapper>
<Modal
width={modalWidth}
open={visible}
Expand All @@ -67,6 +69,7 @@ function ModalConfigView(props: {
footer={null}
styles={{ body: {padding: "0"} }}
zIndex={Layers.modal}
maskClosable={false}
modalRender={(node) => (
<ModalStyled $background={background} onClick={() => {}}>
{node}
Expand All @@ -81,9 +84,9 @@ function ModalConfigView(props: {
items={gridItemCompToGridItems(containerProps.items)}
/>
</Modal>
</ModalWrapper>)
</ModalWrapper>
);
}
}, (prevProps, nextProps) => isEqual(prevProps, nextProps));

const childrenMap = {
container: SimpleContainerComp,
Expand Down
Loading
Loading