Architecture
DynamicForm 3.1 combines the Field Address foundation, optional Adapter / Module / Rule / Compiler preprocessing, and a stable Config / State / Runtime / Consumer / Shared runtime pipeline. It separates logical field identity from value paths while preserving Ant Design Form as the owner of actual values and validation runtime state.
Module Map
External input / ModuleFormConfig
-> Adapter Registry (optional)
-> Rule + Config Compiler (optional)
-> FormConfig
src/index.tsx
-> DynamicFormProvider
-> useStoreInit
-> form-chain-effect-engine
-> FormChainContext
-> FormContent
-> useRuntimeState
-> useFormRuntimeEvents
-> useFieldParticipation
-> FieldComponentRenderer
Important Files
src/adapters/: normalizes module-like, JsonSchema, OpenAPI, and metadata input intoModuleFormConfig.src/modules/: defines theFieldModuleprotocol and module registry.src/rules/: validates and evaluates declarative rules and compiles them into standard effects.src/compiler/compileFormConfig.ts: compilesModuleFormConfiginto standardFormConfigand a component registry.src/CompiledDynamicForm.tsx: wires compiler output and its component registry intoDynamicForm.src/index.tsx: splitsDynamicFormPropsinto engine props and UI props.src/consumer/provider/DynamicFormProvider.tsx: initializes store, effect engine, and React context.src/state/useStoreInit.ts: processes config, creates reducer state, merges initial values, and syncs Ant Design Form.src/config/processor/configParser.ts: createseffectMap,fieldRegistry,initialValues,initializedFields, andinitializedGroupFields.src/state/reducer.ts: handles field meta, group meta, and dynamic UI config updates with Immer.src/runtime/resolver.ts: resolves field and group runtime capabilities.src/consumer/render/FormContent.tsx: renders the form and wires submit/change events.src/consumer/effects/: applies effect results through handlers.src/consumer/render/componentRegistry.tsx: provides built-in components and custom registration.
Data Flow
- An optional adapter normalizes external input into
ModuleFormConfig. - The optional compiler expands field modules, compiles field/group rules, and creates standard
FormConfigplus a component registry. - The user supplies handwritten
FormConfigtoDynamicForm, or compiler output toCompiledDynamicForm. DynamicFormpasses engine props toDynamicFormProviderand UI props toFormContent.useStoreInitcallsprocessFormConfig(formConfig).- Config processing creates dependency maps, field registry, initial values, and initialized field/group state.
- The reducer receives
INITand stores structure, meta, config process info, and dynamic UI config. DynamicFormProviderinitializesform-chain-effect-enginewitheffectMap.FormContentcomputes oneruntimeStatefrom reducer state.- Rendering, validation, and hidden-field participation consume that same
runtimeState. - User input triggers runtime-filtered validation and then the effect engine.
- Effect results pass through
applyEffectResult, and handlers update Ant Design Form values, field meta, group meta, or dynamic UI config.
State Ownership
Ant Design Form owns values, validation errors and warnings, touched and validating state, and submitted value retrieval.
DynamicForm reducer owns flat field state, grouped field state, field behavior/render meta, group behavior meta, config processing info, dynamic UI config, and initialized state.
The reducer intentionally does not maintain a duplicate value store. Effect handlers that update values should call form.setFieldsValue.
Layer Responsibilities
- Adapter Layer: converts external input into
ModuleFormConfigwithout deciding Runtime or renderer behavior. - Module / Compiler Layer: expands domain field modules, assembles flat/grouped/mixed structure, and outputs standard
FormConfig. - Rule Layer: compiles synchronous declarative rules into standard effects without replacing the effect engine or Ant Design validation.
- Config Layer: normalizes flat/grouped/mixed
FormConfiginto runtime inputs. - State Layer: stores initialized field/group structure and meta while normalizing legacy flat meta keys.
- Runtime Layer: resolves rendered, submitable, editable, readonly, disabled, and validatable policy.
- Consumer Layer: connects provider, rendering, hooks, effect results, and component registry.
- Shared Layer: contains types, context, utilities, and meta normalization helpers.
Maintenance Constraints
- Field lookup should use
configProcessInfo.fieldRegistrybecause fields can be flat or grouped. - Runtime should be computed once per state snapshot in
FormContent. - Validation must be filtered through
runtimeState.fields[fieldId].validatable. - Hidden fields are excluded from submit participation unless explicitly preserved.
- Render hooks can bypass default rendering, so extension behavior changes should be deliberate.
- Adapters, the compiler, and the Rule Engine should remain outside React runtime and must not directly own Form instances or reducer state.