React Hook Form(react-hook-form)快速上手指南:基于 Hooks 的表单状态管理与验证(Web + React Native)
2026/9/19 18:39:10 网站建设 项目流程

React Hook Form(react-hook-form)快速上手指南:基于 Hooks 的表单状态管理与验证(Web + React Native)

【免费下载链接】react-hook-form📋 React Hooks for form state management and validation (Web + React Native)项目地址: https://gitcode.com/gh_mirrors/re/react-hook-form

本文以本仓库中的 docs/README.pt-BR.md(葡萄牙语版官方 README)为骨架,结合仓库源码与测试深入展开,讲解 React Hook Form 的核心功能、安装方式与快速上手用法。读完本文,你将掌握如何用useFormregisterhandleSubmiterrors完成非受控表单的注册与验证,了解其验证规则的底层实现,并能在 Web 与 React Native 项目中直接落地。

一、认识 React Hook Form

React Hook Form 是 React 生态中一个基于 Hooks 的表单状态管理与验证库(本仓库 package.json 描述为"Performant, flexible and extensible forms library for React Hooks")。它的设计初衷是用最少的代码、最小的包体积完成表单注册、取值、验证与提交。

官方葡萄牙语文档 docs/README.pt-BR.md 将其核心能力概括为以下特性:

  • 以性能与开发者体验为优先"Construído com performance e experiência do desenvolvedor em mente")——尽量减少不必要的组件重渲染;
  • 非受控表单验证"Validação de formulários incontrolados")——核心 API 走非受控路径,输入值由 DOM 自行持有,表单库只负责读取与验证;
  • 改善受控表单性能"Melhore o desempenho do formulário controlado")——当需要受控组件(如与 UI 库集成)时,通过Controller提供更高效的桥接;
  • 体积小、零依赖"Baixo custo sem nenhuma dependência");
  • 遵循 HTML 标准验证规范"Segue as normas padrões de validação HTML")——requiredminmaxminLengthmaxLengthpattern等规则均对应原生表单语义;
  • 兼容 React Native"Compatível com React Native");
  • 支持 [Yup]、[Joi]、[Superstruct] 或自定义验证方案"Suporta Yup, Joi, Superstruct ou personalizado");
  • 原生支持浏览器内置验证"Suporte nativo a validação do navegador");
  • 可搭配 Form Builder 快速构建"Possibilita construção rápida com form builder")。

从当前仓库源码看,这些特性均可在 src 目录下得到印证:核心 Hook 实现在 src/useForm.ts 与 src/logic/createFormControl.ts,验证规则实现在 src/logic/validateField.ts,可复用的工具函数位于 src/utils。

二、安装

官方文档给出的安装方式为 npm:

$ npm install react-hook-form

仓库内同时提供了pnpm工作区(pnpm-workspace.yaml),因此也可以使用pnpm add react-hook-form。以本仓库开发环境为例,运行pnpm install后通过pnpm start即可启动示例应用(见 package.json 的start脚本:先构建 ESM 产物,再进入 app 目录启动 Vite 开发服务器)。

几点安装相关的实际约束(来自 package.json):

  • React 版本peerDependencies声明为react: "^16.8.0 || ^17 || ^18 || ^19",即要求 React 16.8(Hooks 特性引入版本)及以上;
  • Node 版本engines声明node >= 18.0.0
  • 包导出:通过exports字段区分import(ESM,dist/index.esm.mjs)、require(CJS,dist/index.cjs.js)与react-serverdist/react-server.esm.mjs)三种入口,源码入口为 src/index.ts。

三、快速上手:useForm三件套

官方文档给出了一个极简的快速开始示例(docs/README.pt-BR.md 的"Começo rápido"一节),下面先原样展示,再逐行解读:

import React from 'react'; import { useForm } from 'react-hook-form'; function App() { const { register, handleSubmit, errors } = useForm(); // initialise the hook const onSubmit = (data) => { console.log(data); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input name="firstname" ref={register} /> {/* register an input */} <input name="lastname" ref={register({ required: true })} /> {errors.lastname && 'Last name is required.'} <input name="age" ref={register({ pattern: /\d+/ })} /> {errors.age && 'Please enter number for age.'} <input type="submit" /> </form> ); }

这个例子虽然来自旧版 API(errors直接解构、ref={register}写法),但它完整呈现了 React Hook Form 的三步核心用法

  1. register注册字段:把输入框的ref交给register,该字段即被纳入表单管理,提交时可被读取、可被验证;
  2. handleSubmit包裹提交逻辑:所有字段验证通过后才调用onSubmit(data),验证失败则不会提交;
  3. errors读取错误:以字段名为键,条件渲染错误提示。

3.1 当前版本(V7)的等价写法

当前仓库已是 v7 版本(package.json 中版本号为7.88.0),官方英文 README(README.md)与 V7 版本文档(docs/README.V7.zh-CN.md、docs/README.V7.ja-JP.md)给出了新版写法,差异有两点:

  • errors移动到了formState下:formState: { errors }
  • register从“接收 ref”改为“展开到输入框”:{...register('firstName')}

等价代码为:

import { useForm } from 'react-hook-form'; function App() { const { register, handleSubmit, formState: { errors }, } = useForm(); return ( <form onSubmit={handleSubmit((data) => console.log(data))}> <input {...register('firstName')} /> <input {...register('lastName', { required: true })} /> {errors.lastName && <p>Last name is required.</p>} <input {...register('age', { pattern: /\d+/ })} /> {errors.age && <p>Please enter a number for age.</p>} <input type="submit" /> </form> ); }

本仓库 app/src/basic.tsx 中的示例页面就是这种写法的完整演示:它注册了firstNamerequired)、lastNamerequired+maxLength: 5)、min(数字最小值 10)、max(数字最大值 20)、minDate/maxDate(日期范围)、minLengthpattern: /\d+/radiocheckbox、多选select、自定义validate等多种规则,并展示了嵌套字段(nestItem.nest1)与数组字段(arrayItem.0.test1)的注册方式——字段名使用点号路径即可映射到嵌套数据结构。

3.2useForm返回的核心成员

以当前仓库 src/useForm.ts 的实现为准,useForm的返回值由 src/logic/createFormControl.ts 中的createFormControl创建,主要成员包括:

成员作用
register注册受管字段,接收字段名与验证规则
handleSubmit包装提交回调,验证通过才触发onSubmit
formState.errors字段错误对象,键为字段名
formState其他成员isDirtyisValidisSubmittingtouchedFields等表单状态
watch/getValues/setValue读取与写入字段值
reset重置表单(含resetOptions
trigger手动触发字段验证
setError/clearErrors手动设置/清除错误
setFocus聚焦指定字段
control用于ControlleruseWatchuseFormState等高级 API

3.3handleSubmit的第二个参数

handleSubmit除了接收成功回调,还接收验证失败时的回调。以 app/src/basic.tsx 为例:

const [onInvalidCalledTimes, setOnInvalidCalledTimes] = useState(0); const onInvalid = () => setOnInvalidCalledTimes((prevCount) => prevCount + 1); <form onSubmit={handleSubmit((data) => { setData(data); }, onInvalid)} >

onInvalid会在字段验证不通过时被调用,这在需要统计校验失败、打点埋点或展示全局错误时非常实用。对应的端到端测试见 e2e/basic.spec.ts。

四、验证规则详解(结合源码)

官方文档提到 React Hook Form"Segue as normas padrões de validação HTML"(遵循 HTML 标准验证规范)。这些规则的底层实现集中在 src/logic/validateField.ts,规则常量定义在 src/constants.ts:

export const INPUT_VALIDATION_RULES = { max: 'max', min: 'min', maxLength: 'maxLength', minLength: 'minLength', pattern: 'pattern', required: 'required', validate: 'validate', } as const;

各规则的核心行为(均可从 validateField.ts 源码验证):

  • required:值为true或字符串消息。对普通输入框判空(空字符串、undefinednull均视为空);对复选框要求至少勾选一项(通过getCheckboxValue判断);对单选框要求有选中项(通过getRadioValue判断);布尔值字段要求为true。若required传字符串,该字符串会作为错误消息(见isString(required)分支);
  • min/max:针对数字与日期。源码中优先使用inputRef.valueAsNumber转数字比较,非数字场景(type="date"type="time"type="week")则按日期/时间语义比较(见 validateField.ts 第 132–190 行的分支逻辑);
  • minLength/maxLength:对字符串计算inputValue.length比较;对useFieldArray场景还可作用于数组长度;
  • pattern:接收正则表达式,对字符串执行inputValue.match(patternValue)判断是否匹配;
  • validate:接收函数或对象。函数形式签名是(value, formValues) => boolean | string | Promise<...>,返回true通过、字符串作为错误消息、falseundefined表示失败(由 getValidateError 转为错误);对象形式可同时声明多条规则,每条以键名为type。验证函数支持异步(源码中await validate(inputValue, formValues)),可用于远程校验。

4.1 错误消息与criteriaMode: 'all'

默认情况下,字段验证命中第一条失败规则即返回if (!validateAllFieldCriteria) { return error; })。若想收集某个字段的全部失败规则(如同时违反requiredpattern),可在useForm中开启:

useForm({ criteriaMode: 'all', })

此时errors[fieldName].types会以规则名为键记录所有失败信息。该行为由 src/logic/createFormControl.ts 中的_options.criteriaMode === VALIDATION_MODE.all判定,并通过appendErrors(src/logic/appendErrors.ts)累积多条错误。

4.2 原生浏览器验证(shouldUseNativeValidation

开启该选项后,库会调用输入框的setCustomValidityreportValidity,把验证消息交给浏览器原生 UI 展示(见 validateField.ts 中的setCustomValidity内部实现):

useForm({ shouldUseNativeValidation: true, })

注意:reportValidity属于浏览器环境 API,因此该选项仅在 Web 端生效,React Native 中不会使用。

4.3 验证时机:modereValidateMode

官方文档强调表单库“以性能优先”,其中关键设计就是验证时机可配置useForm支持两个选项(默认值见 createFormControl.ts 第 111–112 行,取值常量见 src/constants.ts 的VALIDATION_MODE):

  • mode:首次验证触发时机,默认onSubmit,可选onBluronChangeonTouchedall
  • reValidateMode再次验证的时机,默认onChange,即提交失败后用户一修改字段就重新校验。

示例(对应 app/src/basic.tsx 通过路由参数切换验证模式):

useForm({ mode: 'onBlur', // 首次验证在字段失焦时触发 reValidateMode: 'onChange', // 之后每次变更都重新验证 })

这两个选项对应的验证行为在源码中由_validationModeBeforeSubmit/_validationModeAfterSubmit两组模式位控制(见 createFormControl.ts 第 201–202 行)。

五、在真实项目中实践

5.1 本仓库的示例应用

本仓库提供了一个完整的 Vite + React 演示应用(app 目录),每个 app/src 下的.tsx文件对应一个独立表单场景,例如:

  • app/src/basic.tsx:基础验证规则全覆盖;
  • app/src/controller.tsx:Controller桥接受控组件;
  • app/src/useFieldArray.tsx:动态字段数组;
  • app/src/useWatch.tsx 与 app/src/watch.tsx:订阅字段值变化;
  • app/src/setValue.tsx / app/src/reset.tsx / app/src/setFocus.tsx:命令式更新与重置;
  • app/src/basicSchemaValidation.tsx:基于 Schema(Resolver)的验证。

每个场景都配有对应的 Playwright 端到端测试(e2e 目录,如 e2e/basic.spec.ts、e2e/useFieldArray.spec.ts),是学习各 API 实际行为的绝佳参照。

5.2 经典示例合集

仓库 examples 目录下按 V6 / V7 两个版本整理了大量可直接复用的示例,例如:

  • examples/V7/basic.tsx:V7 快速开始;
  • examples/V7/basicValidation.tsx:基础验证;
  • examples/V7/conditionalFields.tsx:条件字段;
  • examples/V7/customInput.tsx:自定义输入组件;
  • examples/V7/fieldArrayMinLength.tsx:字段数组长度限制;
  • examples/V7/validationSchema.tsx:外部 Schema 验证。

每个示例都短小完整,可直接复制进自己的项目对照修改。

5.3 与 Schema 验证库(Yup / Joi / Superstruct 等)集成

官方文档明确列出对Yup、Joi、Superstruct 或自定义验证器的支持("Suporta Yup, Joi, Superstruct ou personalizado")。当前版本的集成方式是通过Resolver机制:在useForm中传入resolver选项,把 Schema 解析结果翻译成 React Hook Form 的错误结构。

import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; const schema = yup.object({ name: yup.string().required('Name is required'), age: yup.number().min(18).required(), }); useForm({ resolver: yupResolver(schema), });

仓库中相关示例见 examples/V7/validationSchema.tsx,Resolver 的类型定义位于 src/types/resolvers.ts。需要注意:Resolver 属于独立的@hookform/resolvers生态包,本仓库核心包本身不捆绑任何 Schema 库(这也与“零依赖”的特性一致)。

5.4 React Native 场景

官方文档声明"Compatível com React Native"(兼容 React Native)。实现上的关键差异是:React Native 环境没有浏览器 DOM,因此原生验证(shouldUseNativeValidation)与依赖ref.value/reportValidity的能力不可用,应使用registeronChange/onBlur回调或Controller进行受控桥接。本仓库的源码与文档(docs/README.V7.zh-CN.md)也体现了这一点:核心逻辑通过isWeb(src/utils/isWeb.ts)等工具区分运行环境。

六、性能与体积

官方文档强调库的特点之一是"Baixo custo sem nenhuma dependência"(体积小、无依赖),并*"Construído com performance"*(以性能为构建目标)。结合本仓库可验证的事实包括:

  • 零运行时依赖:本仓库 package.json 的dependencies字段为空,所有依赖均为devDependencies(仅用于构建、测试与类型检查),运行时产物不携带第三方包;
  • 非受控架构:通过ref直接读取 DOM 值,避免输入框每次击键都触发组件级 re-render;formState使用 Proxy 按需订阅(实现见 src/logic/getProxyFormState.ts 与 src/logic/shouldRenderFormState.ts),只有被订阅的字段状态变化才触发渲染;
  • 包体积监控:仓库通过bundlewatch对构建产物做体积阈值监控(package.json 中bundlewatch配置为dist/index.cjs.js上限 15 kB),把体积控制作为发布门禁的一部分。

这些机制共同支撑了“性能优先”的定位。仓库还提供了性能相关测试 src/tests/performance.test.tsx 供深入参考。

七、更多资源与社区

官方文档(docs/README.pt-BR.md)末尾列出了以下资源入口,其中与当前仓库直接对应的部分如下:

资源说明仓库内对应位置
Como iniciar(如何开始)官方入门教程README.md 快速开始部分
API 文档各 API 的完整说明reports/api-extractor.api.md(由 API Extractor 生成)
Exemplos(示例)可复用的代码示例examples 目录
Demonstração(演示)在线演示本仓库的 app 演示应用
FAQA(常见问题)官方 FAQ

另外,本文主题文档还翻译了多语言 README,包括简中 docs/README.zh-CN.md、繁中 docs/README.zh-TW.md、日文 docs/README.ja-JP.md、法文 docs/README.fr-FR.md 等,非英语读者可对照阅读。

八、小结

围绕官方葡萄牙语文档 docs/README.pt-BR.md 的核心内容,本文覆盖了:

  • 安装npm install react-hook-form,及 React ≥ 16.8、Node ≥ 18 的前置要求;
  • 快速上手register+handleSubmit+errors三步用法,并给出 V7 版本的等价写法;
  • 验证规则requiredmin/maxminLength/maxLengthpatternvalidate的行为与源码实现(src/logic/validateField.ts);
  • 高级配置criteriaMode: 'all'shouldUseNativeValidationmode/reValidateMode
  • 生态集成:Resolver 对接 Yup / Joi / Superstruct,React Native 兼容性;
  • 性能定位:零依赖、非受控架构与按需订阅的源码证据。

如果你正在为 React 项目挑选表单方案,可以直接参照本仓库 examples/V7/basic.tsx 起步,再按需查阅 src 源码与 e2e 测试理解底层行为。React Hook Form 的核心哲学始终如一:用最少的代码,把表单的状态、验证与提交管好

【免费下载链接】react-hook-form📋 React Hooks for form state management and validation (Web + React Native)项目地址: https://gitcode.com/gh_mirrors/re/react-hook-form

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询