
Ant Design Form 的dependencies依赖字段机制校验联动与精准局部渲染实战【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-designForm.Item的dependencies属性用于声明字段之间的依赖关系当一个字段所依赖的关联字段值发生变化时该字段会自动触发重新校验与状态更新。本文以 form-dependencies 演示源码见 form-dependencies.tsx为骨架结合 antd 源码中Form.Item的实现约束、完整 API 文档与 FAQ讲解依赖字段的定义方式、校验联动原理、与shouldUpdate/useWatch的边界以及Form.List、setFieldsValue等易踩坑场景。dependencies 是什么字段间的响应式关联antd Form 默认采用增量更新策略只有被修改的字段及其相关组件才会触发重渲染以此获得性能优化。dependencies就是在这种增量模型下声明相关关系的官方属性。官方文档对它的定位非常明确见 API 文档 dependencies 小节当字段间存在依赖关系时使用。如果一个字段设置了dependencies属性那么它所依赖的字段更新时该字段将自动触发更新与校验。其属性签名如下同样记录于 Form.Item API 表属性说明类型默认值dependencies设置依赖字段NamePath[]-其中NamePath既可以是字符串如password也可以是嵌套路径数组如[user, name]用来指向表单 store 中任意深度的字段。一个最常见的实战场景就是注册表单里的密码 / 确认密码校验。下面先从演示 Demo 入手看它究竟怎么用。Demo 逐行拆解密码一致性校验仓库中的演示文档 form-dependencies.md 只给出两句说明中英双语真正的技术含量在其配套源码 form-dependencies.tsx 中。它在一个表单里演示了dependencies的两种典型用法。场景一字段级校验联动密码 确认密码const [form] Form.useForm(); Form form{form} namedependenciesDemo autoCompleteoff style{{ maxWidth: 600 }} layoutvertical Form.Item labelPassword namepassword rules{[{ required: true }]} Input / /Form.Item {/* Field */} Form.Item labelConfirm Password namepassword2 dependencies{[password]} rules{[ { required: true }, ({ getFieldValue }) ({ validator(_, value) { if (!value || getFieldValue(password) value) { return Promise.resolve(); } return Promise.reject( new Error(The new password that you entered do not match!), ); }, }), ]} Input / /Form.Item /Form这里的关键点有三个声明依赖password2通过dependencies{[password]}声明自己依赖password字段校验规则访问全局值校验函数利用规则回调中解构出的getFieldValue(password)读取当前表单 store 中password的最新值与自己value比较不一致则Promise.reject抛出错误一致则Promise.resolve通过触发时机由于声明了依赖当用户修改password时antd 会自动重新执行password2的校验——而不是等到用户再动一次password2才校验。如果没有dependencies那么用户先输入密码、再填写确认密码两者是一致的随后用户回头把password改掉password2却不会主动重新校验页面上会残留校验通过的错误状态。这正是 Demo 顶部Alert提示Try modifyPassword2and then modifyPassword想让你亲身体验的链路先填好两个字段再回头修改第一个观察第二个是否被同步重新校验。从实现上看这属于 Form.Item 级联动的简单模式字段有自己的namedependencies只是额外的重校验触发器。规则对象中({ getFieldValue }) ({ validator })的写法是 rc-field-form 的关联校验惯用法注意它返回的是对象而非直接执行。场景二renderProps 精准局部渲染Demo 的第三段展示了dependencies的另一种能力——让无name的Form.Item仅在依赖字段变化时重渲染{/* Render Props */} Form.Item noStyle dependencies{[password2]} {() ( Typography pOnly Update when codepassword2/code updated:/p pre{JSON.stringify(form.getFieldsValue(), null, 2)}/pre /Typography )} /Form.Item这个Form.Item没有name只配置了noStyle不渲染任何默认 DOM 结构与错误信息和dependencies{[password2]}。它的子节点是 render function渲染逻辑是输出整个表单 store 的 JSON。在 rc-field-form 的订阅模型下带 renderProps 的 Form.Item 需要显式声明什么时候该重渲染声明了dependencies后它只订阅password2字段的变化因此只有password2被修改时这段 JSON 才会刷新你改password这段区域不会重渲染。这在表单中用来渲染与某个字段强相关的辅助信息、或者按依赖字段值切换子字段选项时非常有用也是它与shouldUpdate表单任意变化都重渲染的核心区别。结合源码理解使用约束dependencies的正确用法在 FormItem 实现 中有严格的开发期约束。开发模式下InternalFormItem会根据 props 组合输出 warningshouldUpdate与dependencies互斥见 index.tsxwarning( !(shouldUpdate dependencies), shouldUpdate and dependencies shouldnt be used together. See https://u.ant.design/form-deps., );对应文档 FAQ 中的说明dependencies不应和shouldUpdate一起使用因为这可能带来更新逻辑的混乱。两者都在改变 Form.Item 的更新策略语义却不同dependencies是精确的依赖订阅只监听声明的字段shouldUpdate是全量监听任一字段变化都重渲染。renderProps 必须搭配shouldUpdate或dependencies见 index.tsxwarning( !!(shouldUpdate || dependencies), A Form.Item with a render function must have either shouldUpdate or dependencies., );因为 Form 默认增量更新纯函数式子节点没有更新触发源所以必须有其中一个属性来声明订阅范围否则函数永远不会被重新调用。带dependencies但无name且非 renderProps 时会告警见 index.tsxwarning( dependencies !isRenderProps !hasName ? ... : ..., Must set name or use a render function when dependencies is set., );也就是说dependencies的两种合法姿势是① 配合name做字段级校验联动② 配合 render function子节点为函数做精准订阅渲染。这两类用法在 index.test.tsx 中都有对应的 warning 测试用例如shouldUpdateshouldnt work withdependencies、Must setnameor use a render function whendependenciesis set可作为行为契约参考。更完整的实战注册页密码确认register Demoform-dependencies.tsx 是聚焦单一机制的迷你示例仓库中的 register.tsx 则在完整注册表单里呈现了同一模式在生产形态下的写法包含hasFeedback反馈图标Form.Item namepassword labelPassword rules{[{ required: true, message: Please input your password! }]} hasFeedback Input.Password / /Form.Item Form.Item nameconfirm labelConfirm Password dependencies{[password]} hasFeedback rules{[ { required: true, message: Please confirm your password! }, ({ getFieldValue }) ({ validator(_, value) { if (!value || getFieldValue(password) value) { return Promise.resolve(); } return Promise.reject( new Error(The new password that you entered do not match!), ); }, }), ]} Input.Password / /Form.Item与 Demo 相比这个例子的差异点值得注意使用Input.Password隐藏明文、用hasFeedback让校验状态成功/错误有可视化图标反馈、为required提供了自定义message。当用户修改password后confirm字段的校验会自动重跑若与新密码不一致会立刻在confirm输入框下方出现错误提示并清除通过状态——这就是dependencies在真实业务中最典型的落地形态。依赖的路径边界与易踩坑场景依赖 Form.List 下的字段路径必须完整在 FAQ为什么 Form.Item 的dependencies对 Form.List 下的字段没有效果见 index.zh-CN.md FAQ中官方给出了解释Form.List 下的字段天然包裹在 List 自身的name之下因此依赖路径也要带上 List 前缀。Form.List nameusers {(fields) fields.map((field) ( React.Fragment key{field.key} Form.Item name{[field.name, name]} {...someRest1} / Form.Item name{[field.name, age]} {...someRest1} / /React.Fragment )) } /Form.List此时若要表达对第一行name的依赖写法是dependencies{[[users, 0, name]]}嵌套路径用字符串users或省略 List 前缀都不会命中目标字段。dependencies不响应setFieldsValueFAQ为什么dependencies不能响应setFieldsValue触发的更新index.zh-CN.md FAQ同样是高频疑问。官方答复要点dependencies主要用于字段间的校验联动依赖字段由用户交互触发更新时会重新触发当前字段的更新与校验。如果需要根据setFieldsValue后的值变化来渲染额外内容或切换字段选项请使用shouldUpdate或useWatch。原因在于 antd Form 的 change 事件只在用户交互时触发设计上是为了避免在 change 回调中调用setFieldsValue形成死循环程序化的setFieldsValue不会产生交互式更新链路。与之配套的另一个 FAQsetFieldsValue不会触发onFieldsChange和onValuesChange把这一设计初衷讲得更透需要消费setFieldsValue带来的值变化时请改用useWatch或 renderProps 方案。因此选择依据可归纳为需求推荐方案字段 A 变化后重新校验字段 B用户交互触发dependencies字段 A 变化后按值渲染 B 的选项/辅助 UIdependenciesrenderProps或useWatch表单任意变化都重渲染某区域shouldUpdatetrue 或对比函数监听setFieldsValue程序化赋值后的值useWatch或shouldUpdateuseWatch属于 Hooks 层面的字段订阅比dependencies更灵活地适用于读取字段值派生 UI的场景API 签名为Form.useWatch(namePath, formInstance?)而dependencies的优势在于它与字段校验生命周期深度绑定能同时触发重新校验。小结dependencies是 antd Form 中处理字段间依赖的核心声明式 API它回答的问题是当我改了一个字段哪些字段需要被重新校验、哪些区域需要重新渲染。掌握三个要点即可在生产中游刃有余配name声明依赖后被依赖字段变化会自动触发本字段重新校验典型场景是密码/确认密码一致性校验演示见 form-dependencies.tsx 与 register.tsx配 renderProps无name的 Form.Item 以函数为子节点并声明dependencies可把重渲染精确限定在依赖字段变化时认清边界dependencies与shouldUpdate不可混用、不可省略name或 renderProps、嵌套字段Form.List必须写全路径、且不响应setFieldsValue的程序化赋值——后两类场景请切换到useWatch/shouldUpdate。这些约束在 FormItem 源码 的 warning 逻辑和官方 FAQ 中均有明确依据。理解并正确组合dependencies、shouldUpdate、useWatch就能在 antd 增量更新模型下既拿到联动校验的可靠性又保住大表单的性能。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考