HouseForm 非文本输入处理:Radio、Select 等复杂控件的表单校验实战
HouseForm 非文本输入处理Radio、Select 等复杂控件的表单校验实战【免费下载链接】houseformSimple to use React forms, where your validation and UI code live together in harmony.项目地址: https://gitcode.com/gh_mirrors/ho/houseform在 React 项目中表单可不止文本框这一种形态。当你在构建问卷、设置页或电商下单流程时Radio 单选、Select 下拉、Checkbox 复选这些非文本输入才是真正的拦路虎。本文将围绕HouseForm 非文本输入处理手把手演示如何用这个 headless 的 React 表单库配合 Zod 完成 Radio、Select 等复杂控件的表单校验与状态管理让你的表单代码与校验逻辑真正住在同一屋檐下。HouseForm 是一个以字段为核心Field-first、由 Zod 驱动、完全 headless 的 React 表单校验库。所谓 headless就是它不渲染任何 UI 组件只负责状态与校验逻辑具体长什么样的 Radio、Select 完全由你决定。这意味着你已有的 HTML 控件、UI 组件库如 Ant Design、MUI都可以直接接入无需迁移成本。核心 API 藏在 lib/field/field.tsx 和 lib/form/form.tsx 中。Radio 单选按钮的表单校验实现方法Radio 单选的核心难点在于它由多个input组成却只对应表单中的一个值。HouseForm 的做法非常巧妙——用一个Field包住整组单选按钮通过value与checked的绑定来同步状态。用单个 Field 管理整组 Radio 的选中状态来看官方文档 non-text-inputs.md 中给出的经典例子一组最佳魂系游戏单选每个input typeradio都通过checked{value 选项值}判断选中onChange时调用setValue(e.target.value)写入状态Fieldstring namegame onChangeValidate{z .literal(darksouls) .or(z.literal(bloodborne)) .or(z.literal(sekiro))} {({ value, setValue, onBlur, errors }) ( fieldset legend最佳魂系游戏是/legend input typeradio namegame valuedarksouls checked{value darksouls} onChange{(e) setValue(e.target.value)} / input typeradio namegame valuebloodborne checked{value bloodborne} onChange{(e) setValue(e.target.value)} / {/* 更多选项... */} {errors.map((error) p key{error}{error}/p)} /fieldset )} /Field这段代码的精髓在于校验逻辑与 UI 代码放在同一个Field内一眼就能看清这个字段有哪些合法值、校验不通过时展示什么。errors数组由 HouseForm 自动填充你只需要渲染它。Radio 校验的两种常用校验时机HouseForm 的Field支持四种校验时机详见 types.ts 中的ValidationFunctiononChangeValidate选中即校验适合单选场景体验最即时 ✅onBlurValidate失焦时校验适合用户需要时间考虑的字段onSubmitValidate提交时才校验适合最后兜底onMountValidate挂载时校验可用于回显数据的合法性检查单选场景强烈推荐onChangeValidate因为点击即完成选择用户不需要输入也不存在失焦延迟的问题。Select 下拉框的表单校验与默认值处理Select 比 Radio 更简单——它本身就是一个元素一个值天然契合Field的value模型。你只需把value、onChange、onBlur三件套接好即可。带 optgroup 分组的 Select 校验完整示例Fieldstring namegames onChangeValidate{z.union( [z.literal(ds3), z.literal(eldenring)], { errorMap: () ({ message: 该选项不在支持列表中 }) } )} {({ value, setValue, onBlur, errors }) ( div label htmlForgames选择你最喜欢的游戏/label select value{value} onChange{(e) setValue(e.target.value)} onBlur{onBlur} idgames optgroup labelDark Souls 系列 option valueds1Dark Souls/option option valueds3Dark Souls 3/option /optgroup optgroup label魂系作品 option valueeldenringElden Ring/option option valuesekiroSekiro/option /optgroup /select {errors.map((error) p key{error}{error}/p)} /div )} /Field注意这里用z.union限定合法选项配合errorMap自定义错误文案用户选到非法值时能看到友好提示。长尾技巧Fieldstring的泛型注解让value具备类型提示避免拼写错误。Select 必选校验的推荐配置Select 最常见的坑是默认选中第一项导致必选校验永远通过。推荐组合拳给select的第一个option设为value的占位项如请选择…用z.string().min(1, 请选择一项)做必选校验配合onBlurValidate用户点开下拉又离开时立即提示。这样既保证必选逻辑成立又不会在用户还没操作时过早报错。Checkbox 复选框与更多控件的通用接入思路除了 Radio 和 SelectHouseForm 的 headless 特性让你能接入任意控件套路完全一致拿到value/setValue/onBlur按控件自己的事件模型接上。Checkbox 的选中值是布尔型写法如下Fieldboolean nameagreement initialValue{false} onChangeValidate{z.literal(true, { message: 请先同意用户协议 })} {({ value, setValue, onBlur }) ( input typecheckbox checked{value} onChange{(e) setValue(e.target.checked)} onBlur{onBlur} / )} /Field用initialValue{false}初始化z.literal(true)强制要求勾选——一个完整的协议勾选校验就完成了。同理日期选择器、滑块、评分组件只要你能拿到当前值 变更回调就能无缝接入。实战要点复杂控件表单校验的避坑清单结合 basic-usage.md 和 form.md 的说明总结几条实战经验一个逻辑单元 一个 Field整组 Radio、单个 Select 各自对应一个Field提交后Form的onSubmit(values)会按name汇总所有字段值善用isTouched控制报错时机在errors.map外层加isTouched 避免用户还没触碰就满屏红字见 basic-usage.md校验规则与 UI 同处一处这是 HouseForm 区别于其他表单库的核心卖点改一处 UI 时能同时看到校验规则自定义校验不限于 Zod复杂业务可用异步函数Promise.resolve(true)通过、Promise.reject(错误信息)失败参考 custom-validators.md提交前整体把关用Form暴露的isValid控制提交按钮禁用态用submit()触发onSubmitValidate结语让复杂控件校验回归简单HouseForm 用字段优先 headless Zod 驱动的理念把 Radio、Select 等复杂控件的表单校验从噩梦变成顺手的事。你不需要记住繁琐的注册 API只要把value、setValue、onBlur三件套接到任何控件上校验逻辑就自然生效。若想深入了解字段的类型定义与校验机制可阅读 lib/field/types.ts完整示例见 example/App.tsx。现在就去改造你的第一个 Radio 或 Select 吧【免费下载链接】houseformSimple to use React forms, where your validation and UI code live together in harmony.项目地址: https://gitcode.com/gh_mirrors/ho/houseform创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考