Skip to content

Commit 266ff63

Browse files
committed
fix(Form): setFieldsValue failed in custom controlled form
1 parent 8fcbdbb commit 266ff63

File tree

5 files changed

+50
-47
lines changed

5 files changed

+50
-47
lines changed

packages/components/form/_example/customized-form-controls.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
2-
import { Form, Input, Button, MessagePlugin, Space, Select } from 'tdesign-react';
3-
import type { FormProps } from 'tdesign-react';
2+
import { Button, Form, Input, Select, Space } from 'tdesign-react';
43

54
interface ICourseSelect {
65
value?: {
@@ -27,13 +26,24 @@ function CourseSelect(props: ICourseSelect) {
2726
label: '英语',
2827
value: 'english',
2928
},
29+
{
30+
label: '计算机',
31+
value: 'computer',
32+
},
3033
]}
3134
value={value?.type}
3235
onChange={(v) => {
36+
// type 改变时,清空 name
3337
onChange?.({
34-
...value,
3538
type: v as string,
39+
name: '',
3640
});
41+
42+
// type 改变时,保留 name
43+
// onChange?.({
44+
// ...value,
45+
// type: v as string,
46+
// });
3747
}}
3848
placeholder="请选择课程类型"
3949
/>
@@ -54,21 +64,23 @@ function CourseSelect(props: ICourseSelect) {
5464
export default function BaseForm() {
5565
const [form] = Form.useForm();
5666

57-
const onSubmit: FormProps['onSubmit'] = (e) => {
58-
console.log(e);
59-
if (e.validateResult === true) {
60-
MessagePlugin.info('提交成功');
61-
}
62-
};
63-
6467
return (
65-
<Form form={form} onSubmit={onSubmit} colon labelWidth={100}>
68+
<Form form={form} colon labelWidth={100}>
6669
<FormItem label="课程" name="course">
6770
<CourseSelect />
6871
</FormItem>
6972
<FormItem style={{ marginLeft: 100 }}>
70-
<Button type="submit" theme="primary">
71-
提交
73+
<Button
74+
onClick={() => {
75+
form.setFieldsValue({
76+
course: {
77+
type: 'computer',
78+
name: '操作系统',
79+
},
80+
});
81+
}}
82+
>
83+
设置数据
7284
</Button>
7385
</FormItem>
7486
</Form>

packages/components/form/hooks/useInstance.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { cloneDeep, get, isEmpty, isFunction, merge, set } from 'lodash-es';
1+
import { cloneDeep, isArray, isEmpty, isFunction, isObject, merge, set } from 'lodash-es';
22
import log from '@tdesign/common-js/log/index';
33
import useConfig from '../../hooks/useConfig';
4-
import { calcFieldValue, findFormItem, objectToArray, travelMapFromObject } from '../utils';
4+
import { calcFieldValue, findFormItem, travelMapFromObject } from '../utils';
55

66
import type { FormItemInstance } from '../FormItem';
77
import type {
@@ -149,16 +149,27 @@ export default function useInstance(
149149

150150
// 对外方法,设置对应 formItem 的值
151151
function setFieldsValue(fields = {}) {
152-
const nameLists = objectToArray(fields);
153-
nameLists.forEach((nameList) => {
154-
const fieldValue = get(fields, nameList);
155-
const formItemRef = findFormItem(nameList, formMapRef);
152+
const setValueByPath = (value: any, path: (string | number)[] = []) => {
153+
// 当前路径对应的 FormItem 存在,直接设置
154+
const formItemRef = findFormItem(path, formMapRef);
156155
if (formItemRef?.current) {
157-
formItemRef.current.setValue?.(fieldValue);
156+
formItemRef.current.setValue?.(value);
157+
return;
158+
}
159+
160+
// 递归处理对象
161+
// { user: { name: '' } } => [['user', 'name']]
162+
// { user: [{ name: '' }]} => [['user']]
163+
if (isObject(value) && !isArray(value) && !isEmpty(value)) {
164+
Object.keys(value).forEach((key) => {
165+
setValueByPath(value[key], [...path, key]);
166+
});
158167
} else {
159-
set(floatingFormDataRef.current, nameList, fieldValue);
168+
set(floatingFormDataRef.current, path, value);
160169
}
161-
});
170+
};
171+
172+
setValueByPath(fields);
162173
}
163174

164175
// 对外方法,设置对应 formItem 的数据

packages/components/form/utils/index.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { get, has, isArray, isEmpty, isObject } from 'lodash-es';
1+
import { get, has } from 'lodash-es';
22
import type { FormItemInstance } from '../FormItem';
33
import type { NamePath } from '../type';
44

@@ -62,26 +62,6 @@ function findFormItemDeep(
6262
}
6363
}
6464

65-
// { user: { name: '' } } => [['user', 'name']]
66-
// 不处理数组类型
67-
// { user: [{ name: '' }]} => [['user']]
68-
export function objectToArray(obj: Record<string | number, any>) {
69-
const result: (string | number)[][] = [];
70-
71-
function traverse(current: any, path: string[] = []) {
72-
if (isObject(current) && !isArray(current) && !isEmpty(current)) {
73-
Object.keys(current).forEach((key) => {
74-
traverse(current[key], [...path, key]);
75-
});
76-
} else {
77-
result.push(path);
78-
}
79-
}
80-
81-
traverse(obj);
82-
return result;
83-
}
84-
8565
export function calcFieldValue(name: NamePath, value: any, numericKeyAsIndex = true) {
8666
if (!Array.isArray(name)) return { [name]: value };
8767
let result: any = value;

0 commit comments

Comments
 (0)