Skip to content

Commit f588333

Browse files
authored
Merge pull request #1147 from lowcoder-org/minimize-rerendering
Minimize rerendering
2 parents 1e3d6a6 + 0bf1805 commit f588333

19 files changed

+438
-251
lines changed

client/packages/lowcoder/src/components/PermissionDialog/AppPermissionDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { SHARE_TITLE } from "../../constants/apiConstants";
3131
import { messageInstance } from "lowcoder-design/src/components/GlobalInstances";
3232
import { default as Divider } from "antd/es/divider";
3333

34-
export const AppPermissionDialog = (props: {
34+
export const AppPermissionDialog = React.memo((props: {
3535
applicationId: string;
3636
visible: boolean;
3737
onVisibleChange: (visible: boolean) => void;
@@ -148,7 +148,7 @@ export const AppPermissionDialog = (props: {
148148
}
149149
/>
150150
);
151-
};
151+
});
152152

153153
const InviteInputBtn = styled.div`
154154
display: flex;

client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
DEFAULT_GRID_COLUMNS,
2525
DEFAULT_ROW_HEIGHT,
2626
} from "layout/calculateUtils";
27-
import _ from "lodash";
27+
import _, { isEqual } from "lodash";
2828
import {
2929
ActionExtraInfo,
3030
changeChildAction,
@@ -313,7 +313,7 @@ const ItemWrapper = styled.div<{ $disableInteract?: boolean }>`
313313
pointer-events: ${(props) => (props.$disableInteract ? "none" : "unset")};
314314
`;
315315

316-
const GridItemWrapper = React.forwardRef(
316+
const GridItemWrapper = React.memo(React.forwardRef(
317317
(
318318
props: React.PropsWithChildren<HTMLAttributes<HTMLDivElement>>,
319319
ref: React.ForwardedRef<HTMLDivElement>
@@ -326,11 +326,11 @@ const GridItemWrapper = React.forwardRef(
326326
</ItemWrapper>
327327
);
328328
}
329-
);
329+
));
330330

331331
type GirdItemViewRecord = Record<string, GridItem>;
332332

333-
export function InnerGrid(props: ViewPropsWithSelect) {
333+
export const InnerGrid = React.memo((props: ViewPropsWithSelect) => {
334334
const {
335335
positionParams,
336336
rowCount = Infinity,
@@ -348,11 +348,13 @@ export function InnerGrid(props: ViewPropsWithSelect) {
348348

349349
// Falk: TODO: Here we can define the inner grid columns dynamically
350350
//Added By Aqib Mirza
351-
const defaultGrid =
352-
horizontalGridCells ||
351+
const defaultGrid = useMemo(() => {
352+
return horizontalGridCells ||
353353
currentTheme?.gridColumns ||
354354
defaultTheme?.gridColumns ||
355355
"12";
356+
}, [horizontalGridCells, currentTheme?.gridColumns, defaultTheme?.gridColumns]);
357+
356358
/////////////////////
357359
const isDroppable =
358360
useContext(IsDroppable) && (_.isNil(props.isDroppable) || props.isDroppable) && !readOnly;
@@ -385,7 +387,7 @@ export function InnerGrid(props: ViewPropsWithSelect) {
385387

386388
const canAddSelect = useMemo(
387389
() => _.size(containerSelectNames) === _.size(editorState.selectedCompNames),
388-
[containerSelectNames, editorState]
390+
[containerSelectNames, editorState.selectedCompNames]
389391
);
390392

391393
const dispatchPositionParamsTimerRef = useRef(0);
@@ -432,16 +434,21 @@ export function InnerGrid(props: ViewPropsWithSelect) {
432434
onPositionParamsChange,
433435
onRowCountChange,
434436
positionParams,
435-
props,
437+
props.dispatch,
438+
props.containerPadding,
436439
]
437440
);
438441
const setSelectedNames = useCallback(
439442
(names: Set<string>) => {
440443
editorState.setSelectedCompNames(names);
441444
},
442-
[editorState]
445+
[editorState.setSelectedCompNames]
443446
);
444-
const { width, ref } = useResizeDetector({ onResize, handleHeight: isRowCountLocked });
447+
448+
const { width, ref } = useResizeDetector({
449+
onResize,
450+
handleHeight: isRowCountLocked,
451+
});
445452

446453
const itemViewRef = useRef<GirdItemViewRecord>({});
447454
const itemViews = useMemo(() => {
@@ -464,9 +471,10 @@ export function InnerGrid(props: ViewPropsWithSelect) {
464471
const clickItem = useCallback(
465472
(
466473
e: React.MouseEvent<HTMLDivElement,
467-
globalThis.MouseEvent>, name: string
474+
globalThis.MouseEvent>,
475+
name: string,
468476
) => selectItem(e, name, canAddSelect, containerSelectNames, setSelectedNames),
469-
[canAddSelect, containerSelectNames, setSelectedNames]
477+
[selectItem, canAddSelect, containerSelectNames, setSelectedNames]
470478
);
471479

472480
useEffect(() => {
@@ -555,7 +563,9 @@ export function InnerGrid(props: ViewPropsWithSelect) {
555563
{itemViews}
556564
</ReactGridLayout>
557565
);
558-
}
566+
}, (prevProps, newProps) => {
567+
return isEqual(prevProps, newProps);
568+
});
559569

560570
function selectItem(
561571
e: MouseEvent<HTMLDivElement>,

client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EditorContext } from "comps/editorState";
22
import { EditorContainer } from "pages/common/styledComponent";
3-
import { Profiler, useContext, useRef, useState } from "react";
3+
import React, { Profiler, useContext, useRef, useState } from "react";
44
import styled from "styled-components";
55
import { profilerCallback } from "util/cacheUtils";
66
import {
@@ -20,6 +20,7 @@ import { CanvasContainerID } from "constants/domLocators";
2020
import { CNRootContainer } from "constants/styleSelectors";
2121
import { ScrollBar } from "lowcoder-design";
2222
import { defaultTheme } from "@lowcoder-ee/constants/themeConstants";
23+
import { isEqual } from "lodash";
2324

2425
// min-height: 100vh;
2526

@@ -72,7 +73,7 @@ function getDragSelectedNames(
7273

7374
const EmptySet = new Set<string>();
7475

75-
export function CanvasView(props: ContainerBaseProps) {
76+
export const CanvasView = React.memo((props: ContainerBaseProps) => {
7677
const editorState = useContext(EditorContext);
7778
const [dragSelectedComps, setDragSelectedComp] = useState(EmptySet);
7879
const scrollContainerRef = useRef(null);
@@ -166,4 +167,6 @@ export function CanvasView(props: ContainerBaseProps) {
166167
</EditorContainer>
167168
</CanvasContainer>
168169
);
169-
}
170+
}, (prevProps, newProps) => {
171+
return isEqual(prevProps, newProps);
172+
});

client/packages/lowcoder/src/comps/comps/gridLayoutComp/dragSelector.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const InitialState = {
3838
startPoint: undefined,
3939
};
4040

41-
export class DragSelector extends React.Component<SectionProps, SectionState> {
41+
class DragSelectorComp extends React.Component<SectionProps, SectionState> {
4242
private readonly selectAreaRef: React.RefObject<HTMLDivElement>;
4343

4444
constructor(props: SectionProps) {
@@ -178,3 +178,5 @@ export class DragSelector extends React.Component<SectionProps, SectionState> {
178178
};
179179
}
180180
}
181+
182+
export const DragSelector = React.memo(DragSelectorComp);

client/packages/lowcoder/src/comps/comps/rootComp.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
import RefTreeComp from "./refTreeComp";
3333
import { ExternalEditorContext } from "util/context/ExternalEditorContext";
3434
import { useUserViewMode } from "util/hooks";
35+
import React from "react";
36+
import { isEqual } from "lodash";
3537

3638
const EditorView = lazy(
3739
() => import("pages/editor/editorView"),
@@ -55,7 +57,7 @@ const childrenMap = {
5557
preload: PreloadComp,
5658
};
5759

58-
function RootView(props: RootViewProps) {
60+
const RootView = React.memo((props: RootViewProps) => {
5961
const previewTheme = useContext(ThemeContext);
6062
const { comp, isModuleRoot, ...divProps } = props;
6163
const [editorState, setEditorState] = useState<EditorState>();
@@ -143,7 +145,9 @@ function RootView(props: RootViewProps) {
143145
</PropertySectionContext.Provider>
144146
</div>
145147
);
146-
}
148+
}, (prevProps, nextProps) => {
149+
return isEqual(prevProps, nextProps);
150+
});
147151

148152
/**
149153
* Root Comp

client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> =
4444
version: InstanceType<typeof StringControl>;
4545
};
4646

47-
export function HidableView(props: {
47+
export const HidableView = React.memo((props: {
4848
children: JSX.Element | React.ReactNode;
4949
hidden: boolean;
50-
}) {
50+
}) => {
5151
const { readOnly } = useContext(ExternalEditorContext);
5252
if (readOnly) {
5353
return <>{props.children}</>;
@@ -64,15 +64,15 @@ export function HidableView(props: {
6464
</>
6565
);
6666
}
67-
}
67+
})
6868

69-
export function ExtendedPropertyView<
69+
export const ExtendedPropertyView = React.memo(<
7070
ChildrenCompMap extends Record<string, Comp<unknown>>,
7171
>(props: {
7272
children: JSX.Element | React.ReactNode,
7373
childrenMap: NewChildren<ChildrenCompMap>
7474
}
75-
) {
75+
) => {
7676
const [compVersions, setCompVersions] = useState(['latest']);
7777
const [compName, setCompName] = useState('');
7878
const editorState = useContext(EditorContext);
@@ -129,7 +129,7 @@ export function ExtendedPropertyView<
129129
)}
130130
</>
131131
);
132-
}
132+
});
133133

134134
export function uiChildren<
135135
ChildrenCompMap extends Record<string, Comp<unknown>>,
@@ -275,11 +275,11 @@ export const DisabledContext = React.createContext<boolean>(false);
275275
/**
276276
* Guaranteed to be in a react component, so that react hooks can be used internally
277277
*/
278-
function UIView(props: {
278+
const UIView = React.memo((props: {
279279
innerRef: React.RefObject<HTMLDivElement>;
280280
comp: any;
281281
viewFn: any;
282-
}) {
282+
}) => {
283283
const comp = props.comp;
284284
const childrenProps = childrenToProps(comp.children);
285285
const childrenJsonProps = comp.toJsonValue();
@@ -397,13 +397,12 @@ function UIView(props: {
397397
width: '100%',
398398
height: '100%',
399399
margin: '0px',
400-
padding:getPadding()
401-
400+
padding: getPadding()
402401
}}
403402
>
404403
<HidableView hidden={childrenProps.hidden as boolean}>
405404
{props.viewFn(childrenProps, comp.dispatch)}
406405
</HidableView>
407406
</div>
408407
);
409-
}
408+
});

client/packages/lowcoder/src/index.sdk.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import * as styledNameExports from "styled-components";
66
import styledDefault from "styled-components";
77
export * as styledm from "styled-components";
88
export * from "comps/comps/containerBase/containerCompBuilder";
9+
export * from "comps/comps/containerBase/iContainer";
10+
export * from "comps/comps/containerBase/utils";
11+
export * from "comps/comps/containerBase/simpleContainerComp";
912
export * from "comps/utils/backgroundColorContext";
1013
export { getData } from "comps/comps/listViewComp/listViewUtils";
1114
export { gridItemCompToGridItems, InnerGrid } from "comps/comps/containerComp/containerView";
15+
export type { ContainerBaseProps } from "comps/comps/containerComp/containerView";
1216

1317
export { Layers } from "constants/Layers";
1418
export * from "comps/controls/eventHandlerControl";
@@ -97,6 +101,7 @@ export * from "comps/controls/simpleStringControl";
97101
export * from "comps/controls/stringSimpleControl";
98102
export * from "comps/controls/styleControl";
99103
export * from "comps/controls/styleControlConstants";
104+
export * from "comps/controls/slotControl";
100105

101106
// generators
102107
export * from "comps/generators/changeDataType";
@@ -114,6 +119,7 @@ export * from "comps/generators/withExposing";
114119
export * from "comps/generators/withIsLoading";
115120
export * from "comps/generators/withMethodExposing";
116121
export * from "comps/generators/withType";
122+
export * from "comps/generators/controlCompBuilder";
117123

118124
export * from "appView/bootstrapAt";
119125
export * from "appView/LowcoderAppView";

client/packages/lowcoder/src/layout/compSelectionWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ const HiddenIcon = styled(CloseEyeIcon)`
231231
}
232232
`;
233233

234-
export const CompSelectionWrapper = (props: {
234+
export const CompSelectionWrapper = React.memo((props: {
235235
id?: string;
236236
compType: UICompType;
237237
className?: string;
@@ -376,4 +376,4 @@ export const CompSelectionWrapper = (props: {
376376
</SelectableDiv>
377377
</div>
378378
);
379-
};
379+
});

0 commit comments

Comments
 (0)