用途
React Hook Form + Zod 用于在 React 应用中构建带校验的类型安全表单。它把三件事组合在一起:表单状态管理、schema 校验、TypeScript 类型推断。资料描述其目标是让同一份 schema 在客户端和服务端复用,做到 DRY 校验,并且从 schema 推导类型,使前后端类型保持一致。项目状态标注为生产可用(Production Ready),最后更新时间为 2025-11-20,依赖标注为无(独立使用)。
主要能力
- 表单状态管理:react-hook-form 被描述为性能好、灵活、重渲染最少的表单库。
- schema 校验与类型推断:zod 是 TypeScript 优先的 schema 校验工具,支持基本类型、对象、数组、可选/可空、默认值、联合类型、枚举、嵌套对象、自定义错误消息,以及 refine(自定义校验,含异步)和 transform(数据转换)。
- 适配层:@hookform/resolvers 把 Zod(以及其他校验器)连接到 React Hook Form,其中 zodResolver 负责把 Zod schema 转成 React Hook Form 能理解的格式、在提交时运行校验、把 Zod 错误映射为表单错误格式,并保留类型推断。
- 服务端校验:同一份 Zod schema 可在服务端 parse 请求体,并用 error.flatten().fieldErrors 把错误返回客户端。
- 动态字段与自定义组件:提供 useFieldArray 处理字段数组,提供 Controller 和 useController 接入不暴露 ref 的第三方或自定义组件。
使用方式
安装
npm install react-hook-form@7.66.1 zod@4.1.12 @hookform/resolvers@5.2.2
资料称完成快速上手约需 10 分钟。
定义 schema 与类型
用 z.object({...}) 定义校验规则,用 z.infer<typeof schema> 自动推导表单数据类型。资料中的登录示例包含邮箱格式校验和密码最小长度校验。
初始化表单
调用 useForm<FormData>({ resolver: zodResolver(schema), defaultValues: {...} })。useForm 返回 register、handleSubmit、watch、formState、setValue、getValues、reset、trigger、control 等。资料列出可配置项包括 resolver、mode、reValidateMode、defaultValues、shouldUnregister、criteriaMode。校验模式有 onSubmit(默认,性能最好)、onChange(实时反馈,重渲染更多)、onBlur(平衡)、all(最灵敏,开销最高)。
注册字段
- 原生 HTML 输入:使用
register('fieldName'),返回 onChange、onBlur、ref、name,展开到 input 上即可。 - 自定义或第三方组件:使用 Controller,通过 render 拿到 field(value、onChange、onBlur、ref)与 fieldState;或用 useController 封装可复用的受控输入组件。资料明确建议标准 HTML 输入优先用 register,而不是 Controller。
展示错误
通过 formState.errors 访问字段错误对象(含 type 和 message),可用 role="alert" 做无障碍提示,可设置 aria-invalid。表单级错误可通过 refine 不指定 path 生成 root 错误,用 errors.root?.message 读取。
处理服务端错误
提交时若接口返回错误,遍历错误对象并用 setError(field, { type: 'server', message }) 回填到对应字段;通用错误可写入 setError('root', ...)。
动态字段
使用 useFieldArray({ control, name: 'contacts' }) 拿到 fields、append、remove,schema 中对数组用 z.array(...).min(1) 约束。
适用场景
- 需要在 React 中构建带校验的表单;
- 希望用一份 schema 同时覆盖客户端与服务端校验;
- 希望在前后端共享 TypeScript 类型;
- 需要接入 React Select、Material-UI、Ant Design 等第三方组件、日期选择器或不暴露 ref 的自定义组件;
- 需要动态增删字段的表单(如联系人列表)。
关键注意事项与限制
- 资料强调必须设置 defaultValues,否则会出现 uncontrolled 到 controlled 的警告。
- 客户端校验可以被绕过(改元素、用 Postman 或 curl),因此服务端必须再校验一次,服务端校验才是安全层。
- 使用 zodResolver(schema) 连接校验,用 z.infer 获得完整类型安全。
- 校验模式的选择会影响性能与响应性,需按场景权衡。
- 资料未提供收费、价格、平台限制或性能基准数据。
版本与依赖
资料给出的版本为 react-hook-form@7.66.1、zod@4.1.12、@hookform/resolvers@5.2.2。除上述三个包外,依赖标注为无。