React 复杂表单处理(Hook Form + Zod)
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_15292d5a/yjkj-fec-form-handling。
技能介绍
复杂表单为什么容易「越填越卡」
字段一多、出现动态项、联动校验、文件上传或多步流程时,若每个 onChange 都驱动整表重渲染,或校验逻辑散落在组件里,输入延迟和状态不一致会很快暴露。更麻烦的是:只靠 TypeScript 类型无法约束运行时入参,服务端错误也难映射到具体字段。
这套流程在做什么
技能把「要不要上库」和「怎么接上库」拆成可执行的步骤:
- 复杂度判断:10+ 字段、动态字段、联动、上传、多步或已感到卡顿 → 用 React Hook Form + Zod;极简场景可保留原生受控组件。
- Schema 先行:用 Zod 定义运行时 schema,并用
z.infer推导 TS 类型;schema 作为外部输入边界,不单写类型。 - 统一挂载:
useForm必须提供完整defaultValues,经zodResolver校验;错误用aria-invalid、aria-describedby、role="alert"暴露给辅助技术。 - 单一状态源:第三方受控组件走
Controller,原生input优先register,避免两套状态混用。 - 提交与性能:处理 loading、服务端错误、防重复提交与
reset;大表单用局部订阅、子组件隔离重渲染。
进阶主题(Controller、useFieldArray、联动、上传、多步、异步校验、性能模式)在 references/advanced-form-patterns.md 中展开。
边界与约束
React Hook Form 默认非受控;仅第三方受控组件需要 Controller。defaultValues 必须完整,避免 undefined 触发受控/非受控警告;reset() 应传入服务端返回或明确的完整默认对象。异步校验需 debounce 或放到提交边界;Zod 的 refine / superRefine 的 path 必须指向真实字段名。
使用场景
- 管理后台有 10 个以上字段,需要统一 defaultValues 与 zodResolver,避免每次输入整页重渲染
- 动态增减表单项(如联系人列表)时,用 useFieldArray 与 schema 约束,并保持单一状态源
- 多步注册或审批流要在各步间校验、提交,并把服务端字段错误回填到对应控件
- 第三方 UI 库的 Select、DatePicker 等受控组件需用 Controller 接入,同时满足 aria 错误提示
适合人员
- 负责中后台 CRUD 页的前端工程师,表单含联动校验与文件上传且已出现输入卡顿
- 用 React + TypeScript 做 B 端产品的全栈或前端,希望 schema 同时约束运行时入参与类型推导
- 维护设计系统表单组件的开发者,需要把第三方受控控件与 register 原生字段统一到一套提交流程
- 做无障碍合规的前端,要在复杂表单上落实 aria-describedby 与 role="alert" 的错误展示