diff --git a/src/hooks/useForm.ts b/src/hooks/useForm.ts index 3353d8e61..620b6d4d2 100644 --- a/src/hooks/useForm.ts +++ b/src/hooks/useForm.ts @@ -293,8 +293,21 @@ export class FormStore { // Ignore when it's a list item and not specific the namePath, // since parent field is already take in count if ((entity as FieldEntity).isList?.()) { - listNamePaths.push(namePath); - return; + // 这里直接跳过跟节点是有bug的,getFieldsValue("list") 会返回空对象 + const hasChild = fieldEntities.some(other => { + if (other === entity) return false; + const otherNamePath = other.INVALIDATE_NAME_PATH || other.getNamePath(); + return ( + otherNamePath.length > namePath.length && + matchNamePath(otherNamePath as InternalNamePath, namePath as InternalNamePath, true) + ); + }); + + // 只有当它确实有子节点时,才跳过根节点 + if (hasChild) { + listNamePaths.push(namePath); + return; + } } if (!mergedFilterFunc) { diff --git a/tests/list.test.tsx b/tests/list.test.tsx index 8c312d313..521f23288 100644 --- a/tests/list.test.tsx +++ b/tests/list.test.tsx @@ -1171,4 +1171,31 @@ describe('Form.List', () => { list: [{ name: 'A' }, { name: 'BB' }, { name: 'C' }, { name: 'D' }], }); }); + + it('getFieldsValue(["list"]) should keep list value when list has value but no child Field entities', async () => { + const [container] = generateForm( + () => ( + { + form.current!.setFieldValue(['list', 0, 'name'], (e.target as HTMLInputElement).value); + }} + /> + ), + { + initialValues: { + list: [{ name: '123' }], + }, + }, + ); + + expect(form.current!.getFieldsValue(['list'])).toEqual({ list: [{ name: '123' }] }); + + await act(async () => { + fireEvent.change(container.querySelector('input.raw-name')!, { target: { value: '456' } }); + }); + + expect(form.current!.getFieldsValue(['list'])).toEqual({ list: [{ name: '456' }] }); + }); });