Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c2680f3

Browse files
optimise modal comp
1 parent 05ee98b commit c2680f3

File tree

2 files changed

+109
-44
lines changed

2 files changed

+109
-44
lines changed

‎client/packages/lowcoder/src/comps/hooks/hookComp.tsx‎

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import _ from "lodash";
2727
import dayjs from "dayjs";
2828
import { ConstructorToComp } from "lowcoder-core";
2929
import { ScrollBar, Section, sectionNames } from "lowcoder-design";
30-
import React, { useContext, useEffect, useMemo } from "react";
30+
import React, { useContext, useEffect, useMemo,useCallback } from "react";
3131
import { useInterval, useTitle, useWindowSize } from "react-use";
3232
import { useCurrentUser } from "util/currentUser";
3333
import { LocalStorageComp } from "./localStorageComp";
@@ -53,9 +53,16 @@ const CurrentUserHookComp = hookToStateComp(() => {
5353

5454
function useCurrentTime() {
5555
const [time, setTime] = React.useState(0);
56-
useInterval(() => {
57-
setTime(new Date().getTime());
58-
}, 1000);
56+
57+
// Add cleanup for the interval
58+
useEffect(() => {
59+
const interval = setInterval(() => {
60+
setTime(new Date().getTime());
61+
}, 1000);
62+
63+
return () => clearInterval(interval);
64+
}, []);
65+
5966
return useMemo(
6067
() => ({
6168
time: time,
@@ -126,6 +133,23 @@ function SelectHookView(props: {
126133
const editorState = useContext(EditorContext);
127134
const selectedComp = editorState.selectedComp();
128135

136+
// Memoize the comp tree calculation
137+
const compTree = useMemo(() => {
138+
if (!props.comp || !(props.comp as any).getCompTree) return null;
139+
return (props.comp as any).getCompTree();
140+
}, [props.comp]);
141+
142+
// Memoize the child components calculation
143+
const allChildComp = useMemo(() => {
144+
if (!compTree) return {};
145+
return getAllCompItems(compTree);
146+
}, [compTree]);
147+
148+
// Memoize the click handler
149+
const handleClick = useCallback(() => {
150+
editorState.setSelectedCompNames(new Set([props.compName]));
151+
}, [editorState, props.compName]);
152+
129153
// Select the modal and its subcomponents on the left to display the modal
130154
useEffect(() => {
131155
if (
@@ -151,7 +175,6 @@ function SelectHookView(props: {
151175
);
152176
} else {
153177
// all child components of modal
154-
const allChildComp = getAllCompItems((props.comp as any).getCompTree());
155178
const selectChildComp = Object.values(allChildComp).find(
156179
(child) => child === selectedComp
157180
);
@@ -166,14 +189,10 @@ function SelectHookView(props: {
166189
);
167190
}
168191
}
169-
}, [selectedComp, editorState.selectSource]);
192+
}, [selectedComp, editorState.selectSource,allChildComp]);
170193

171194
return (
172-
<div
173-
onClick={() =>
174-
editorState.setSelectedCompNames(new Set([props.compName]))
175-
}
176-
>
195+
<div onClick={handleClick}>
177196
{props.children}
178197
</div>
179198
);

‎client/packages/lowcoder/src/comps/hooks/modalComp.tsx‎

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Layers } from "constants/Layers";
1414
import { HintPlaceHolder, Modal, Section, sectionNames } from "lowcoder-design";
1515
import { trans } from "i18n";
1616
import { changeChildAction } from "lowcoder-core";
17-
import { CSSProperties, useCallback } from "react";
17+
import { CSSProperties, useCallback,useMemo,useRef } from "react";
1818
import { ResizeHandle } from "react-resizable";
1919
import styled, { css } from "styled-components";
2020
import { useUserViewMode } from "util/hooks";
@@ -116,19 +116,36 @@ let TmpModalComp = (function () {
116116
(props, dispatch) => {
117117
const userViewMode = useUserViewMode();
118118
const appID = useApplicationId();
119-
const bodyStyle: CSSProperties = { padding: 0 };
120-
const width = transToPxSize(props.width || DEFAULT_WIDTH);
121-
let height = undefined;
122-
let resizeHandles: ResizeHandle[] = ["w", "e"];
123-
if (!props.autoHeight) {
124-
height = transToPxSize(props.height || DEFAULT_HEIGHT);
125-
resizeHandles.push("s");
126-
bodyStyle.overflow = "hidden auto";
127-
}
128-
if (userViewMode) {
129-
resizeHandles = [];
130-
}
131-
const { items, ...otherContainerProps } = props.container;
119+
const containerRef = useRef<HTMLElement | null>(null);
120+
121+
// Memoize body style
122+
const bodyStyle = useMemo<CSSProperties>(() => ({
123+
padding: 0,
124+
overflow: props.autoHeight ? undefined : "hidden auto"
125+
}), [props.autoHeight]);
126+
127+
// Memoize width and height
128+
const width = useMemo(() =>
129+
transToPxSize(props.width || DEFAULT_WIDTH),
130+
[props.width]
131+
);
132+
133+
const height = useMemo(() =>
134+
!props.autoHeight ? transToPxSize(props.height || DEFAULT_HEIGHT) : undefined,
135+
[props.autoHeight, props.height]
136+
);
137+
138+
// Memoize resize handles
139+
const resizeHandles = useMemo<ResizeHandle[]>(() => {
140+
if (userViewMode) return [];
141+
const handles: ResizeHandle[] = ["w", "e"];
142+
if (!props.autoHeight) {
143+
handles.push("s");
144+
}
145+
return handles;
146+
}, [userViewMode, props.autoHeight]);
147+
148+
// Memoize resize handler
132149
const onResizeStop = useCallback(
133150
(
134151
e: React.SyntheticEvent,
@@ -144,13 +161,48 @@ let TmpModalComp = (function () {
144161
},
145162
[dispatch]
146163
);
147-
let paddingValues = [10, 10];
148-
if (props.style.padding != undefined) {
164+
165+
// Memoize padding values
166+
const paddingValues = useMemo(() => {
167+
if (!props.style.padding) return [10, 10];
149168
const extractedValues = extractMarginValues(props.style);
150-
if (extractedValues !== null) {
151-
paddingValues = extractedValues;
152-
}
153-
}
169+
return extractedValues || [10, 10];
170+
}, [props.style.padding]);
171+
172+
// Memoize container getter
173+
const getContainer = useCallback(() => {
174+
if (!containerRef.current) {
175+
containerRef.current = document.querySelector(`#${CanvasContainerID}`) || document.body;
176+
}
177+
return containerRef.current;
178+
}, []);
179+
180+
// Memoize event handlers
181+
const handleCancel = useCallback((e: React.MouseEvent) => {
182+
if (props.toggleClose) {
183+
props.visible.onChange(false);
184+
}
185+
}, [props.toggleClose, props.visible]);
186+
187+
const handleAfterClose = useCallback(() => {
188+
if (props.toggleClose) {
189+
props.onEvent("close");
190+
}
191+
}, [props.toggleClose, props.onEvent]);
192+
193+
const handleAfterOpenChange = useCallback((open: boolean) => {
194+
if (open) {
195+
props.onEvent("open");
196+
}
197+
}, [props.onEvent]);
198+
199+
// Memoize modal render function
200+
const modalRender = useCallback((node: React.ReactNode) => (
201+
<ModalStyled $style={props.style} $modalScrollbar={props.modalScrollbar}>
202+
{node}
203+
</ModalStyled>
204+
), [props.style, props.modalScrollbar]);
205+
154206
return (
155207
<BackgroundColorContext.Provider value={props.style.background}>
156208
<ModalWrapper>
@@ -162,30 +214,24 @@ let TmpModalComp = (function () {
162214
open={props.visible.value}
163215
maskClosable={props.maskClosable}
164216
focusTriggerAfterClose={false}
165-
getContainer={()=>document.querySelector(`#${CanvasContainerID}`)||document.body}
217+
getContainer={getContainer}
166218
footer={null}
167219
styles={{body: bodyStyle}}
168220
title={props.title}
169221
$titleAlign={props.titleAlign}
170222
width={width}
171-
onCancel={(e) => {
172-
props.toggleClose&&props.visible.onChange(false);
173-
}}
174-
afterClose={() => {
175-
props.toggleClose&&props.onEvent("close");
176-
}}
177-
afterOpenChange={(open: boolean) => {
178-
if (open) props.onEvent("open");
179-
}}
223+
onCancel={handleCancel}
224+
afterClose={handleAfterClose}
225+
afterOpenChange={handleAfterOpenChange}
180226
zIndex={Layers.modal}
181-
modalRender={(node)=><ModalStyled$style={props.style}$modalScrollbar={props.modalScrollbar}>{node}</ModalStyled>}
227+
modalRender={modalRender}
182228
mask={props.showMask}
183229
className={clsx(`app-${appID}`, props.className)}
184230
data-testid={props.dataTestId as string}
185231
>
186232
<InnerGrid
187-
{...otherContainerProps}
188-
items={gridItemCompToGridItems(items)}
233+
{...props.container}
234+
items={gridItemCompToGridItems(props.container.items)}
189235
horizontalGridCells={props.horizontalGridCells}
190236
autoHeight={props.autoHeight}
191237
minHeight={paddingValues ? DEFAULT_HEIGHT - paddingValues[0] * 2 + "px" : ""}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /