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 05ee98b

Browse files
optimise form components
1 parent 0543b12 commit 05ee98b

File tree

13 files changed

+559
-256
lines changed

13 files changed

+559
-256
lines changed

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

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,16 @@ export const InnerGrid = React.memo((props: ViewPropsWithSelect) => {
397397
);
398398

399399
const dispatchPositionParamsTimerRef = useRef(0);
400+
401+
// Add cleanup for timeout
402+
useEffect(() => {
403+
return () => {
404+
if (dispatchPositionParamsTimerRef.current) {
405+
window.clearTimeout(dispatchPositionParamsTimerRef.current);
406+
}
407+
};
408+
}, []);
409+
400410
const onResize = useCallback(
401411
({width, height}: ResizePayload) => {
402412
if(!width || !height) return;
@@ -444,20 +454,35 @@ export const InnerGrid = React.memo((props: ViewPropsWithSelect) => {
444454
props.dispatch,
445455
]
446456
);
447-
const setSelectedNames = useCallback(
448-
(names: Set<string>) => {
449-
editorState?.setSelectedCompNames(names);
450-
},
451-
[editorState?.setSelectedCompNames]
452-
);
453457

458+
// Cleanup resize detector
454459
const { width, ref } = useResizeDetector({
455460
onResize,
456461
handleHeight: isRowCountLocked,
457462
refreshMode: 'debounce',
458463
refreshRate: 100,
459464
});
460465

466+
const setSelectedNames = useCallback(
467+
(names: Set<string>) => {
468+
editorState?.setSelectedCompNames(names);
469+
},
470+
[editorState?.setSelectedCompNames]
471+
);
472+
473+
// Cleanup item references when items are removed
474+
useEffect(() => {
475+
const currentKeys = new Set(Object.keys(props.items));
476+
const refKeys = new Set(Object.keys(itemViewRef.current));
477+
478+
// Remove references to items that no longer exist
479+
refKeys.forEach(key => {
480+
if (!currentKeys.has(key)) {
481+
delete itemViewRef.current[key];
482+
}
483+
});
484+
}, [props.items]);
485+
461486
const itemViewRef = useRef<GirdItemViewRecord>({});
462487
const itemViews = useMemo(() => {
463488
const newView: GirdItemViewRecord = {};

‎client/packages/lowcoder/src/comps/comps/formComp/createForm.tsx‎

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
TacoButton,
1313
} from "lowcoder-design";
1414
import _ from "lodash";
15-
import { useEffect, useState } from "react";
15+
import { useEffect, useState,useCallback } from "react";
1616
import { useDispatch, useSelector } from "react-redux";
1717
import { AppState } from "redux/reducers";
1818
import { fetchDatasourceStructure } from "redux/reduxActions/datasourceActions";
@@ -552,13 +552,22 @@ const CreateFormBody = (props: { onCreate: CreateHandler }) => {
552552
const dataSourceId: string | undefined = Form.useWatch("dataSourceId", form);
553553
const dataSourceItems = useDataSourceItems();
554554
const dataSourceItem = dataSourceItems.find((t) => t.dataSource.id === dataSourceId);
555+
556+
// Cleanup form on unmount
557+
useEffect(() => {
558+
return () => {
559+
form.resetFields();
560+
};
561+
}, [form]);
562+
555563
// default to the first item
556564
useEffect(() => {
557565
if (!dataSourceItem) {
558566
const id = dataSourceItems.length > 0 ? dataSourceItems[0].dataSource.id : undefined;
559567
form.setFieldsValue({ dataSourceId: id });
560568
}
561-
}, [dataSourceItems]);
569+
}, [dataSourceItems, dataSourceItem, form]);
570+
562571
// Refetch when changed
563572
const dispatch = useDispatch();
564573
useEffect(() => {
@@ -570,25 +579,27 @@ const CreateFormBody = (props: { onCreate: CreateHandler }) => {
570579
const tableName: string | undefined = Form.useWatch("tableName", form);
571580
const tableStructures = useTableStructures(dataSourceId);
572581
const tableStructure = tableStructures.find((t) => t.name === tableName);
582+
573583
// default to the first one
574584
useEffect(() => {
575585
if (!tableStructure) {
576586
const name = tableStructures.length > 0 ? tableStructures[0].name : undefined;
577587
form.setFieldsValue({ tableName: name });
578588
}
579-
}, [tableStructures]);
589+
}, [tableStructures, tableStructure, form]);
590+
580591
// Columns of the data table, saved to support drag and drop
581592
const [items, setItems] = useState<RowItem[]>([]);
582593
const dataSourceTypeConfig = dataSourceItem?.typeConfig;
594+
583595
useEffect(() => {
584596
const { initItems, initColumns } = getInitItemsAndColumns(dataSourceTypeConfig, tableStructure);
585597
// Set the initial value by the method. Because if another table has the same column name, setting via initialValue is invalid.
586598
form.setFieldsValue({ columns: initColumns });
587599
setItems(initItems);
588-
}, [dataSourceTypeConfig, tableStructure]);
600+
}, [dataSourceTypeConfig, tableStructure,form]);
589601

590-
const handleDragEnd = (e: { active: { id: string }; over: { id: string } | null }) => {
591-
console.log('handleDragEnd', e);
602+
const handleDragEnd = useCallback((e: { active: { id: string }; over: { id: string } | null }) => {
592603
if (!e.over) {
593604
return;
594605
}
@@ -603,7 +614,7 @@ const CreateFormBody = (props: { onCreate: CreateHandler }) => {
603614
newData.splice(toIndex, 0, movedItem);
604615

605616
setItems(newData);
606-
};
617+
},[items]);
607618

608619
const emptyText = getEmptyText(dataSourceItems.length, tableStructures.length, items.length);
609620

@@ -688,27 +699,40 @@ const CreateFormBody = (props: { onCreate: CreateHandler }) => {
688699

689700
export const CreateForm = (props: { onCreate: CreateHandler }) => {
690701
const [visible, setVisible] = useState(false);
702+
703+
const handleMouseDown = useCallback((e: React.MouseEvent) => {
704+
setVisible(true);
705+
e.stopPropagation();
706+
}, []);
707+
708+
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
709+
e.stopPropagation();
710+
}, []);
711+
712+
const handleClick = useCallback((e: React.MouseEvent) => {
713+
e.stopPropagation();
714+
}, []);
715+
716+
const handleCancel = useCallback(() => {
717+
setVisible(false);
718+
}, []);
719+
691720
return (
692721
<>
693-
<OpenDialogButton
694-
onMouseDown={(e) => {
695-
setVisible(true);
696-
e.stopPropagation();
697-
}}
698-
>
722+
<OpenDialogButton onMouseDown={handleMouseDown}>
699723
{trans("formComp.openDialogButton")}
700724
</OpenDialogButton>
701725
<div
702-
onKeyDown={(e)=>e.stopPropagation()}
703-
onMouseDown={(e)=>e.stopPropagation()}
704-
onClick={(e)=>e.stopPropagation()}
726+
onKeyDown={handleKeyDown}
727+
onMouseDown={handleMouseDown}
728+
onClick={handleClick}
705729
>
706730
<CustomModal
707731
open={visible}
708732
destroyOnClose={true}
709733
title={trans("formComp.generateForm")}
710734
footer={null}
711-
onCancel={()=>setVisible(false)}
735+
onCancel={handleCancel}
712736
width="600px"
713737
children={<CreateFormBody {...props} />}
714738
styles={{ body: {padding: 0} }}

‎client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,18 @@ function onCreate(
169169
const BodyPlaceholder = (props: FormProps) => {
170170
const editorState = useContext(EditorContext);
171171
const formName = useContext(CompNameContext);
172+
173+
const handleCreate = (data: CreateData) => {
174+
const result = onCreate(data, props, editorState, formName);
175+
return Promise.resolve(result);
176+
};
177+
172178
return (
173179
<ContainerPlaceholder>
174180
{trans("formComp.containerPlaceholder")}
175181
<br />
176182
<CreateForm
177-
onCreate={(data: CreateData) =>
178-
Promise.resolve(onCreate(data, props, editorState, formName))
179-
}
183+
onCreate={handleCreate}
180184
/>
181185
</ContainerPlaceholder>
182186
);

‎client/packages/lowcoder/src/comps/comps/formComp/formDataConstants.tsx‎

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { RecordConstructorToComp } from "lowcoder-core";
22
import { StringControl } from "comps/controls/codeControl";
33
import { CompNameContext, EditorContext } from "comps/editorState";
44
import { Section } from "lowcoder-design";
5-
import { ReactNode } from "react";
5+
import { ReactNode,useContext,useMemo } from "react";
66
import { trans } from "i18n";
77

88
export interface IForm {
@@ -17,24 +17,26 @@ export const formDataChildren = {
1717

1818
type FormDataComp = RecordConstructorToComp<typeof formDataChildren>;
1919

20-
export const FormDataPropertyView = (children: FormDataComp) => (
21-
<EditorContext.Consumer>
22-
{(editorState) => (
23-
<CompNameContext.Consumer>
24-
{(name) => (
25-
<>
26-
{editorState?.findUIParentContainer(name, "form") && (
27-
<Section name={trans("form")}>
28-
{children.formDataKey.propertyView({
29-
label: trans("formComp.name"),
30-
placeholder: name,
31-
tooltip: trans("formComp.nameTooltip"),
32-
})}
33-
</Section>
34-
)}
35-
</>
36-
)}
37-
</CompNameContext.Consumer>
38-
)}
39-
</EditorContext.Consumer>
40-
);
20+
export const FormDataPropertyView = (children: FormDataComp) => {
21+
const editorState = useContext(EditorContext);
22+
const name = useContext(CompNameContext);
23+
24+
const isFormParent = useMemo(() =>
25+
editorState?.findUIParentContainer(name, "form"),
26+
[editorState, name]
27+
);
28+
29+
if (!isFormParent) {
30+
return null;
31+
}
32+
33+
return (
34+
<Section name={trans("form")}>
35+
{children.formDataKey.propertyView({
36+
label: trans("formComp.name"),
37+
placeholder: name,
38+
tooltip: trans("formComp.nameTooltip"),
39+
})}
40+
</Section>
41+
);
42+
};

0 commit comments

Comments
(0)

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