Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/hooks/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个性能有点炸,如果一个大表单里的某个 List 没有 children 会导致全部遍历。其实最简单的应该是无论是否有 children 都初始化一个空的 array 就行了。剩下的让 children 自己去填。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getFieldsValue(["list"])调用的时候fieldEntities不会有children;就会导致一致是[];

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) {
Expand Down
27 changes: 27 additions & 0 deletions tests/list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
() => (
<input
className="raw-name"
defaultValue="123"
onChange={e => {
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' }] });
});
});