尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

深入formik-antd源码:Field封装、事件桥接与forwardRef的三大组件封装模式

深入formik-antd源码:Field封装、事件桥接与forwardRef的三大组件封装模式 深入formik-antd源码Field封装、事件桥接与forwardRef的三大组件封装模式【免费下载链接】formik-antdSimple declarative bindings for Ant Design and Formik.项目地址: https://gitcode.com/gh_mirrors/fo/formik-antdformik-antd 是一个为 Ant Design 和 Formik 提供简洁声明式绑定的开源表单组件库只要给 Input、Select、Checkbox 等 antd 组件加一个name属性它就能自动同步到 Formik 表单状态无需手写任何 onChange 胶水代码。这篇文章带你用最短的路径读懂它的源码拆解Field 封装、事件桥接、forwardRef三大组件封装模式帮你掌握把第三方 UI 库接入表单状态管理的通用套路。为什么需要 formik-antd先用一句话说明它解决的问题Formik负责表单状态初始值、值变更、校验、提交Ant Design负责 UIInput、Select、DatePicker 等几十个组件两者直接组合时每个组件都要手写value onChange onBlur的胶水代码非常啰嗦。formik-antd 的思路极其克制它不发明新 API只是把 antd 的组件包一层加一个name属性就完成与 Formik 字段的绑定import { Form, Input, Checkbox } from formik-antd Form Input namefirstName placeholderFirst Name / Checkbox namenewsletter订阅/Checkbox /Form组件的所有其他属性placeholder、min、options……与 antd 官方保持完全一致。安装也很简单npm install formik-antd。如果要阅读源码可以克隆仓库git clone https://gitcode.com/gh_mirrors/fo/formik-antd。全部组件在 src/index.ts 中统一导出每个组件一个独立目录如src/input/、src/select/目录里除了组件源码还带style/子目录用于按需引入 CSS。模式一Field 封装 —— 一个 name 把组件接入表单所有组件的接线工作都由同一个内部组件 Field 完成源码只有十几行位于 src/field/index.tsxexport const Field ({ fast, children, ...restProps }) { if (fast) { return FastField {...restProps}{children}/FastField } return FormikField {...restProps}{children}/FormikField }它做的事情只有两件透传 Formik 的 render propsfield.value、field.onChange、form.setFieldValue等能力从这一层注入给组件一键切换 FastField通过fast属性可选开启 Formik 的性能优化大表单场景才需要。配合 src/FieldProps.tsx 中定义的全库统一表单接口——name必填、validate字段级校验函数、fast性能开关任何 antd 组件只要包一层Field name...就成为 Formik 表单的一员。✅模式二事件桥接 —— 统一 antd 五花八门的 onChange这是源码里最有价值的部分。antd 各组件的 onChange 签名并不统一formik-antd 用三种桥接写法把它们映射到 Formik① 原生事件直通Input / Mentionsantd 的 Input 与原生 input 一样onChange 回调收到 DOM 事件可以直接把 Formik 的field.onChange(event)原样传下去调用完 Formik 后再执行用户自己的 onChange见 src/input/index.tsx$Input value{value} onChange{(event) { onChange(event) // 交给 Formik $onChange $onChange(event) // 再交给用户 }} /② setFieldValue setFieldTouchedCheckbox / Switch / Radio这些组件的 onChange 传的是值而不是事件如checked、event.target.value且失焦时机需要手动标记让校验在正确时机触发。以 src/checkbox/index.tsx 为例$Checkbox checked{value} onChange{(event) { setFieldValue(name, event.target.checked) setFieldTouched(name, true, false) onChange onChange(event) }} /③ 失焦时标记 touchedSelect / AutoComplete下拉类组件的 onChange 直接返回选中值甚至带第二个参数 option是否编辑过更适合在失焦时判断见 src/select/index.tsx、src/auto-complete/index.tsx。 特例数据类型转换也发生在桥接层DatePicker 把 moment 对象转成 ISO 字符串存入表单回填时再转回 momentsrc/date-picker/index.tsxSelect 把空字符串/null 映射为undefined这样才能正确显示 placeholderTable 更特殊它只绑定dataSource做只读连接配合 AddRowButton / RemoveRowButton 操作数组行src/table/index.tsx、src/add-row-button/index.tsx。桥接层的设计原则就一句话表单里存纯数据UI 层负责格式转换这样提交时的values永远是可直接序列化的 JSON。模式三forwardRef —— 把命令式能力留给用户有些场景必须拿到组件实例输入框自动聚焦、提交前清空文本等。为此 Input 家族使用React.forwardRef把 ref 原样透传给底层 antd 组件src/input/index.tsxconst Input React.forwardRef((props, ref) ( Field name{props.name} validate{props.validate} fast{props.fast} {({ field: { value, onChange, onBlur } }) ( $Input ref{ref} name{props.name} value{value} ... / )} /Field ))forwardRef 的妙处在于组合外层用函数式组件消化 Formik 逻辑内层用 forwardRef 保留 ref 通道两者互不干扰。同一个文件里还用静态属性模式挂载了Input.Password和Input.TextArea让用户从formik-antd导入时与从antd导入的写法完全一致。三大封装模式速查表模式核心手段代表组件源码位置Field 封装Field name... render propsfast开关切换 FastField全部 20 组件src/field/index.tsx事件桥接直通 / setFieldValue / setFieldTouched 三种写法 数据转换Input、Checkbox、Select、DatePickersrc/checkbox/index.tsxforwardRefref 透传 静态属性挂载子组件Input / Input.Password / Input.TextAreasrc/input/index.tsx其他值得一看的模块Form组合了 antd Form 的布局与 Formik Form 的提交能力src/form/form.tsxSubmitButton / ResetButton 会根据表单状态自动禁用FormikDebug 可把整个表单状态打印到页面上调试时很好用src/formik-debug/index.tsx。新手实践建议先抄模式再谈优化想给自己的项目封装一套表单组件库时照抄Field 封装 事件桥接两件套即可forwardRef 仅在需要实例方法时再加。fast默认不开只有当表单字段特别多、出现明显卡顿时才给高频变更的字段加fast属性。字段级校验写在validate上如果组件外面套了Form.Itemvalidate要写在Form.Item上而不是输入组件上。类型支持库自带 TypeScript 类型构建配置见 package.jsonname属性在类型层是必填的。测试参考src/tests/mocks.js 与各组件目录下的*.test.tsx展示了如何 mock antd 组件做单元测试。写在最后formik-antd 源码量很小却把把第三方 UI 组件接入表单状态管理这件事讲得很完整Field 封装解决怎么接事件桥接解决数据怎么流forwardRef 解决实例能力怎么留。读懂这一百多行核心封装你基本就掌握了自行实现同类绑定层的全部套路。项目采用 MIT 协议LICENSE欢迎直接阅读、借鉴与贡献。【免费下载链接】formik-antdSimple declarative bindings for Ant Design and Formik.项目地址: https://gitcode.com/gh_mirrors/fo/formik-antd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表