From b8dbd9d88d1034de42e2b4ff153b6a2bb0840840 Mon Sep 17 00:00:00 2001 From: SyMind Date: Sat, 5 Aug 2023 11:57:15 +0800 Subject: [PATCH] fix(form): unexpected validate error before unRegister --- packages/semi-ui/form/__test__/field.test.js | 41 +++++++++++++++++++- packages/semi-ui/form/hoc/withField.tsx | 12 ++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/packages/semi-ui/form/__test__/field.test.js b/packages/semi-ui/form/__test__/field.test.js index e7ded3ea69..3f29e5e4e3 100644 --- a/packages/semi-ui/form/__test__/field.test.js +++ b/packages/semi-ui/form/__test__/field.test.js @@ -1,6 +1,4 @@ import { Form, Select } from '../../index'; -import { noop } from 'lodash'; -import { func } from 'prop-types'; import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants'; import { sleep as baseSleep } from '../../_test_/utils/index'; @@ -459,6 +457,45 @@ describe('Form-field', () => { expect(formApi.getError('text')).not.toBeUndefined(); }); + it('validate before unRegister', async () => { + let formApi = null; + + const Foo = () => ( +
{ + formApi = api; + }} + > + {({ formState }) => ( + <> + {!!formState.values.text && ( + + )} + + )} + + ); + + const form = mount(); + const event = { target: { value: '' } }; + form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event); + await sleep(200); + form.update(); + + formApi.setValue('text', 'foo'); + expect(await formApi.validate()).toEqual({ + text: 'foo', + }); + }); + // TODO // it('allowEmptyString', () => {}); // it('extraText') diff --git a/packages/semi-ui/form/hoc/withField.tsx b/packages/semi-ui/form/hoc/withField.tsx index 8ea14e20eb..ba0858b1c7 100644 --- a/packages/semi-ui/form/hoc/withField.tsx +++ b/packages/semi-ui/form/hoc/withField.tsx @@ -175,6 +175,12 @@ function withField< setStatus('default'); }; + + const unmounted = useRef(false); + useEffect(() => () => { + unmounted.current = true; + }, []); + // Execute the validation rules specified by rules const _validateInternal = (val: any, callOpts: CallOpts) => { let latestRules = rulesRef.current || []; @@ -196,6 +202,9 @@ function withField< if (validatePromise.current !== rootPromise) { return; } + if (unmounted.current) { + return; + } // validation passed setStatus('success'); updateError(undefined, callOpts); @@ -205,6 +214,9 @@ function withField< if (validatePromise.current !== rootPromise) { return; } + if (unmounted.current) { + return; + } let { errors, fields } = err; if (errors && fields) { let messages = errors.map((e: any) => e.message);