diff --git a/src/Field.tsx b/src/Field.tsx index be5a13c2..7aaa266d 100644 --- a/src/Field.tsx +++ b/src/Field.tsx @@ -392,7 +392,7 @@ class Field extends React.Component implements F const namePath = this.getNamePath(); const currentValue = this.getValue(); - const { triggerName, validateOnly = false } = options || {}; + const { triggerName, validateOnly = false, delayFrame: showDelayFrame } = options || {}; // Force change to async to avoid rule OOD under renderProps field const rootPromise = Promise.resolve().then(async (): Promise => { @@ -404,7 +404,9 @@ class Field extends React.Component implements F // Should wait for the frame render, // since developer may `useWatch` value in the rules. - await delayFrame(); + if (showDelayFrame) { + await delayFrame(); + } // Start validate let filteredRules = this.getRules(); diff --git a/src/hooks/useForm.ts b/src/hooks/useForm.ts index 12f99f9d..ebbefd92 100644 --- a/src/hooks/useForm.ts +++ b/src/hooks/useForm.ts @@ -747,7 +747,10 @@ export class FormStore { private triggerDependenciesUpdate = (prevStore: Store, namePath: InternalNamePath) => { const childrenFields = this.getDependencyChildrenFields(namePath); if (childrenFields.length) { - this.validateFields(childrenFields); + this.validateFields(childrenFields, { + // Delay to avoid `useWatch` dynamic adjust rules that deps not get latest one + delayFrame: true, + }); } this.notifyObservers(prevStore, childrenFields, { diff --git a/src/interface.ts b/src/interface.ts index f533be61..f18799a8 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -157,6 +157,7 @@ export type ValidateFields = { export interface InternalValidateOptions extends ValidateOptions { triggerName?: string; validateMessages?: ValidateMessages; + delayFrame?: boolean; } export type InternalValidateFields = { diff --git a/tests/context.test.tsx b/tests/context.test.tsx index 2a68ab13..4a587c9f 100644 --- a/tests/context.test.tsx +++ b/tests/context.test.tsx @@ -6,8 +6,6 @@ import InfoField from './common/InfoField'; import { changeValue, matchError, getInput } from './common'; import timeout from './common/timeout'; -jest.mock('../src/utils/delayUtil'); - describe('Form.Context', () => { it('validateMessages', async () => { const { container } = render( diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 8cafc91f..f6ab2dbf 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -7,9 +7,7 @@ import { changeValue, getInput, matchError } from './common'; import InfoField, { Input } from './common/InfoField'; import timeout, { waitFakeTime } from './common/timeout'; -jest.mock('../src/utils/delayUtil'); import type { FormRef, Meta } from '@/interface'; - describe('Form.Basic', () => { describe('create form', () => { const Content: React.FC = () => ( diff --git a/tests/list.test.tsx b/tests/list.test.tsx index a491b83a..9aac91b3 100644 --- a/tests/list.test.tsx +++ b/tests/list.test.tsx @@ -10,8 +10,6 @@ import InfoField, { Input } from './common/InfoField'; import { changeValue, getInput } from './common'; import timeout from './common/timeout'; -jest.mock('../src/utils/delayUtil'); - describe('Form.List', () => { const form = React.createRef(); diff --git a/tests/validate-warning.test.tsx b/tests/validate-warning.test.tsx index 4a142c40..84b0b6a8 100644 --- a/tests/validate-warning.test.tsx +++ b/tests/validate-warning.test.tsx @@ -5,8 +5,6 @@ import { changeValue, getInput, matchError } from './common'; import type { FormInstance, Rule } from '../src/interface'; import { render } from '@testing-library/react'; -jest.mock('../src/utils/delayUtil'); - describe('Form.WarningValidate', () => { it('required', async () => { const form = React.createRef();