Skip to content
16 changes: 13 additions & 3 deletions packages/components/form/FormList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { castArray, get, isEqual, merge, set, unset } from 'lodash-es';
import { castArray, cloneDeep, get, isEqual, merge, set, unset } from 'lodash-es';

import log from '@tdesign/common-js/log/index';
import { FormListContext, useFormContext, useFormListContext } from './FormContext';
import { HOOK_MARK } from './hooks/useForm';
Expand Down Expand Up @@ -37,7 +38,14 @@ const FormList: React.FC<TdFormListProps> = (props) => {
return propsInitialData;
}, [fullPath, parentFullPath, initialDataFromForm, parentInitialData, props.initialData]);

const [formListValue, setFormListValue] = useState(() => get(form?.store, fullPath) || initialData || []);
const [formListValue, setFormListValue] = useState(() => {
const value = cloneDeep(get(form?.store, fullPath) || initialData || []);
if (value.length && !get(form?.store, fullPath)) {
set(form?.store, fullPath, value);
}
return value;
});

const [fields, setFields] = useState<FormListField[]>(() =>
formListValue.map((data, index) => ({
data: { ...data },
Expand Down Expand Up @@ -66,6 +74,8 @@ const FormList: React.FC<TdFormListProps> = (props) => {
if (!isChildField) return;
const fieldName = itemPathArray[itemPathArray.length - 1];
// add 没有传参时,构建一个包含所有子字段的对象用于占位,确保回调给用户的数据结构完整
// 兼容 add() 或者 add({}) 导致的空对象场景
// https://github.com/Tencent/tdesign-react/issues/2329
defaultValues[fieldName] = item.current.initialData;
});
return defaultValues;
Expand All @@ -88,7 +98,7 @@ const FormList: React.FC<TdFormListProps> = (props) => {
name: index,
isListField: true,
});
const newFormListValue = [...formListValue];
const newFormListValue = cloneDeep(formListValue);
if (defaultValue !== undefined) {
newFormListValue.splice(index, 0, defaultValue);
} else {
Expand Down
6 changes: 3 additions & 3 deletions packages/components/form/_example/form-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ export default function BaseForm() {
<FormList name="task">
{(fields, { add, remove, move }) => (
<>
{fields.map(({ key, name, ...restField }, index) => (
{fields.map(({ key, name }, index) => (
<FormItem key={key}>
<FormItem name={[name, 'type']} label="类型" {...restField}>
<FormItem name={[name, 'type']} label="类型">
<Select options={taskTypeOptions} />
</FormItem>

<FormItem name={[name, 'notes']} label="备注" initialData="排期中" {...restField}>
<FormItem name={[name, 'notes']} label="备注" initialData="排期中">
<Input />
</FormItem>

Expand Down
5 changes: 2 additions & 3 deletions packages/components/form/_example/nested-data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,16 @@ export default function BaseForm() {
<FormList name={['user', 'address']}>
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name, ...restField }) => (
{fields.map(({ key, name }) => (
<FormItem key={key}>
<FormItem
{...restField}
name={[name, 'province']}
label="省份"
rules={[{ required: true, type: 'error' }]}
>
<Input />
</FormItem>
<FormItem {...restField} name={[name, 'area']} label="地区" rules={[{ required: true, type: 'error' }]}>
<FormItem name={[name, 'area']} label="地区" rules={[{ required: true, type: 'error' }]}>
<Input />
</FormItem>
<FormItem>
Expand Down
14 changes: 5 additions & 9 deletions packages/components/form/hooks/useFormItemInitialData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { get, unset, isEmpty, has } from 'lodash-es';
import { get, unset, isEmpty } from 'lodash-es';

// 兼容特殊数据结构和受控 key
import Tree from '../../tree/Tree';
Expand Down Expand Up @@ -66,21 +66,17 @@ export default function useFormItemInitialData(name: NamePath, fullPath: NamePat
}

if (formListName && Array.isArray(fullPath)) {
const pathPrefix = fullPath.slice(0, -1);
const pathExisted = has(form.store, pathPrefix);
if (pathExisted) {
// 只要路径存在,哪怕值为 undefined 也取 store 里的值
// 兼容 add() 或者 add({}) 导致的空对象场景
// https://github.com/Tencent/tdesign-react/issues/2329
return get(form.store, fullPath);
const storeValue = get(form.store, fullPath);
if (typeof storeValue !== 'undefined') {
return storeValue;
}
}

if (typeof initialData !== 'undefined') {
return initialData;
}

if (name && formListInitialData.length) {
if (name && formListInitialData?.length) {
const defaultInitialData = get(formListInitialData, name);
if (typeof defaultInitialData !== 'undefined') return defaultInitialData;
}
Expand Down
Loading