From e8ce5038a6d0dabf7f13194e5b25a69ec64c1a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Wed, 26 Jul 2023 20:50:29 +0800 Subject: [PATCH] feat: support Form.STRICT (#605) * feat: support Form.STRICT * refactor: use config --- src/interface.ts | 7 ++++++- src/useForm.ts | 34 ++++++++++++++++++++++++++++------ tests/list.test.tsx | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/interface.ts b/src/interface.ts index 575d468c..223a954a 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -242,11 +242,16 @@ type RecursivePartial = NonNullable extends object } : T; +export type FilterFunc = (meta: Meta) => boolean; + +export type GetFieldsValueConfig = { strict?: boolean; filter?: FilterFunc }; + export interface FormInstance { // Origin Form API getFieldValue: (name: NamePath) => StoreValue; getFieldsValue: (() => Values) & - ((nameList: NamePath[] | true, filterFunc?: (meta: Meta) => boolean) => any); + ((nameList: NamePath[] | true, filterFunc?: FilterFunc) => any) & + ((config: GetFieldsValueConfig) => any); getFieldError: (name: NamePath) => string[]; getFieldsError: (nameList?: NamePath[]) => FieldError[]; getFieldWarning: (name: NamePath) => string[]; diff --git a/src/useForm.ts b/src/useForm.ts index 3558f4b5..bb57a0f5 100644 --- a/src/useForm.ts +++ b/src/useForm.ts @@ -23,6 +23,8 @@ import type { InternalValidateOptions, ValuedNotifyInfo, WatchCallBack, + FilterFunc, + GetFieldsValueConfig, } from './interface'; import { allPromiseFinish } from './utils/asyncUtil'; import { merge } from 'rc-util/lib/utils/set'; @@ -265,15 +267,31 @@ export class FormStore { }); }; - private getFieldsValue = (nameList?: NamePath[] | true, filterFunc?: (meta: Meta) => boolean) => { + private getFieldsValue = ( + nameList?: NamePath[] | true | GetFieldsValueConfig, + filterFunc?: FilterFunc, + ) => { this.warningUnhooked(); - if (nameList === true && !filterFunc) { + // Fill args + let mergedNameList: NamePath[] | true; + let mergedFilterFunc: FilterFunc; + let mergedStrict: boolean; + + if (nameList === true || Array.isArray(nameList)) { + mergedNameList = nameList; + mergedFilterFunc = filterFunc; + } else if (nameList && typeof nameList === 'object') { + mergedStrict = nameList.strict; + mergedFilterFunc = nameList.filter; + } + + if (mergedNameList === true && !mergedFilterFunc) { return this.store; } const fieldEntities = this.getFieldEntitiesForNamePathList( - Array.isArray(nameList) ? nameList : null, + Array.isArray(mergedNameList) ? mergedNameList : null, ); const filteredNameList: NamePath[] = []; @@ -283,15 +301,19 @@ export class FormStore { // Ignore when it's a list item and not specific the namePath, // since parent field is already take in count - if (!nameList && (entity as FieldEntity).isListField?.()) { + if (mergedStrict) { + if ((entity as FieldEntity).isList?.()) { + return; + } + } else if (!mergedNameList && (entity as FieldEntity).isListField?.()) { return; } - if (!filterFunc) { + if (!mergedFilterFunc) { filteredNameList.push(namePath); } else { const meta: Meta = 'getMeta' in entity ? entity.getMeta() : null; - if (filterFunc(meta)) { + if (mergedFilterFunc(meta)) { filteredNameList.push(namePath); } } diff --git a/tests/list.test.tsx b/tests/list.test.tsx index 60c4cac4..574e7a75 100644 --- a/tests/list.test.tsx +++ b/tests/list.test.tsx @@ -855,4 +855,37 @@ describe('Form.List', () => { expect(onValuesChange).toHaveBeenCalledWith({ name: 'little' }, { name: 'little', age: 2 }); }); + + it('getFieldsValue with Strict mode', () => { + const formRef = React.createRef(); + + const initialValues = { list: [{ bamboo: 1, light: 3 }], little: 9 }; + + mount( +
+
+ + + + + {fields => + fields.map(field => ( + + + + )) + } + +
+
, + ); + + // expect(formRef.current.getFieldsValue()).toEqual(initialValues); + + // Strict only return field not list + expect(formRef.current.getFieldsValue({ strict: true })).toEqual({ + list: [{ bamboo: 1 }], + little: 9, + }); + }); });