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
30 changes: 28 additions & 2 deletions src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
matchNamePath,
setValue,
} from './utils/valueUtil';
import isEqual from 'rc-util/lib/isEqual';

type InvalidateFieldEntity = { INVALIDATE_NAME_PATH: InternalNamePath };

Expand Down Expand Up @@ -580,15 +581,40 @@ export class FormStore {
const { name, ...data } = fieldData;
const namePath = getNamePath(name);
namePathList.push(namePath);
const hasValue = 'value' in data;

const previousFieldEntity = this.getFieldEntitiesForNamePathList(namePath)[0]
let previousFieldMeta: Meta | null = null;

if (previousFieldEntity && !('INVALIDATE_NAME_PATH' in previousFieldEntity)) {
previousFieldMeta = previousFieldEntity.getMeta();
}

let mergeTouched: boolean | undefined = previousFieldMeta?.touched

if ('touched' in data) {
mergeTouched = data.touched;
} else if (hasValue && previousFieldMeta !== null) {
mergeTouched = !isEqual(this.getFieldValue(namePath), data.value)
Copy link
Member

Choose a reason for hiding this comment

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

不能在 setFields 里改 touched 来解决 setFieldValue 里没有设置 touched 的问题。setFields 本身是底层操作,它只改传入的 meta。

应该是 setFieldValue 里直接加上 touched: true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

应该是 setFieldValue 里直接加上 touched: true

value 没有 diff 也算吗?

}

// Meta
const nextFieldMeta: Meta = {
...previousFieldMeta,
...(typeof mergeTouched === 'boolean' ? { touched: mergeTouched } : {})
};

// Value
if ('value' in data) {
if (hasValue) {
this.updateStore(setValue(this.store, namePath, data.value));
}

this.notifyObservers(prevStore, [namePath], {
type: 'setField',
data: fieldData,
data: {
...nextFieldMeta,
...fieldData,
},
});
});

Expand Down
31 changes: 30 additions & 1 deletion tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ describe('Form.Basic', () => {
});
});

it('setFieldValue should always set touched', async () => {
it('setFieldsValue should always set touched', async () => {
const EMPTY_VALUES = { light: '', bamboo: [] };
const formRef = React.createRef<FormRef>();

Expand Down Expand Up @@ -997,6 +997,35 @@ describe('Form.Basic', () => {
expect(formRef.current?.getFieldError('bamboo')).toHaveLength(0);
});

// https://github.com/ant-design/ant-design/issues/53981
it('setFieldValue should mark the registered fields as touched', async () => {
const formRef = React.createRef<FormRef>();

const Demo: React.FC = () => (
<Form ref={formRef}>
<Field name="light" rules={[{ required: true }]}>
<Input />
</Field>
</Form>
);

render(<Demo />);

// Mock error first
await act(async () => {
await formRef.current?.validateFields().catch(() => {});
});
expect(formRef.current?.getFieldError('light')).toHaveLength(1);
expect(formRef.current?.isFieldTouched('light')).toBeFalsy();

await act(async () => {
formRef.current?.setFieldValue('light', 'Bamboo');
await Promise.resolve();
});
expect(formRef.current?.getFieldError('light')).toHaveLength(0);
expect(formRef.current?.isFieldTouched('light')).toBeTruthy();
})

it('setFieldValue should reset errors', async () => {
const formRef = React.createRef<FormRef>();

Expand Down