表单是用户与 Web 应用程序和 Web 应用程序交互的重要组成部分。验证通过表单传递的用户数据是开发人员的一项重要责任。
React Hook Form 是一个帮助在 React 中验证表单的库。它是一个没有任何其他依赖项的最小库,并且性能卓越且易于使用,与其他表单库相比,开发人员需要编写的代码行数更少。
React 19 引入了内置的表单处理。那么,你可能会问:React Hook Form 还值得使用吗?在本指南中,您将了解 2025 年 React Hook Form 的差异、优势和最佳用例。
什么是 React Hook Form?
React Hook Form 采用的方法与 React 生态系统中的其他表单库略有不同,它使用不受控制的输入,而不是依赖于状态来控制输入。此方法使表单性能更高,并减少重新渲染的次数。这也意味着 React Hook Form 提供了与 UI 库的无缝集成,因为大多数库都支持该属性。ref
ref
React Hook Form 的大小非常小(压缩和 gzip 压缩后只有 8.6 kB),并且零依赖性。该 API 也非常直观,为开发人员提供了无缝体验。该库遵循 HTML 标准,使用基于约束的验证 API 来验证表单。
要安装 React Hook Form,请运行以下命令:
npm install react-hook-form
如何在表单中使用 React Hooks
在本节中,您将通过创建一个非常基本的注册表单来了解 Hook 的基础知识。useForm
首先,从包中导入 Hook:useForm
react-hook-form
import { useForm } from "react-hook-form";
然后,在您的组件中,使用 Hook,如下所示:
const { register, handleSubmit } = useForm();
Hook 返回一个包含一些属性的对象。现在,我们只要求 和 。useForm
register
handleSubmit
该方法帮助你将输入字段注册到 React Hook Form 中,以便它可以用于验证,并且可以跟踪其值以进行更改。register
要注册输入,我们将方法传递到输入字段中,如下所示:register
<input type="text" name="firstName" {...register('firstName')} />
此扩展运算符语法是库中的一种新实现,它支持使用 TypeScript 对表单进行严格的类型检查。你可以在这里了解更多关于 React Hook Form 中严格类型检查的信息。
早于 v7 的 React Hook Form 版本将方法附加到该属性上,如下所示:register
ref
<input type="text" name="firstName" ref={register} />
请注意,input 组件必须具有 prop,并且其值应该是唯一的。顾名思义,该方法管理表单提交。它需要作为值传递给组件的 prop。name
handleSubmit
onSubmit
form
该方法可以将两个函数作为参数处理。当表单验证成功时,作为参数传递的第一个函数将与注册的字段值一起调用。验证失败时,第二个函数被调用并出现错误:handleSubmit
const onFormSubmit = data => console.log(data);const onErrors = errors => console.error(errors);<form onSubmit={handleSubmit(onFormSubmit, onErrors)}> {/* ... */}</form>
现在你已经对 Hook 的基本用法有了大致的了解,让我们看看一个更实际的例子:useForm
import React from "react";import { useForm } from "react-hook-form";const RegisterForm = () => { const { register, handleSubmit } = useForm(); const handleRegistration = (data) => console.log(data); return ( <form onSubmit={handleSubmit(handleRegistration)}> <div> <label>Name</label> <input name="name" {...register('name')} /> </div> <div> <label>Email</label> <input type="email" name="email" {...register('email')} /> </div> <div> <label>Password</label> <input type="password" name="password" {...register('password')} /> </div> <button>Submit</button> </form> );};export default RegisterForm;
如您所见,没有导入其他组件来跟踪输入值。Hook 使组件代码更简洁、更易于维护,并且由于表单不受控制,因此您不必将 props like 和 传递给每个输入。useForm
onChange
value
您可以使用您选择的任何其他 UI 库来创建表单。但首先,请确保检查文档并找到用于访问本机 input 组件的 reference 属性的 prop。
在下一节中,您将学习如何在刚刚构建的表单中处理表单验证。
如何使用 React Hook Form 验证表单
要将验证应用于字段,您可以将验证参数传递给该方法。验证参数类似于现有的 HTML 表单验证标准。这些验证参数包括以下属性:register
-
required
指示该字段是否为必填字段。如果此属性设置为 ,则字段不能为空true
-
minlength
并设置字符串输入值的最小和最大长度maxlength
-
min
并设置数值的最小值和最大值max
-
type
指示输入字段的类型;它可以是电子邮件、数字、文本或任何其他标准 HTML 输入类型 -
pattern
使用正则表达式定义输入值的模式
如果要将字段标记为 ,则代码应如下所示:required
<input name="name" type="text" {...register('name', { required: true } )} />
现在尝试在提交此字段为空的情况下提交表单。这将导致以下错误对象:
{name: { type: "required", message: "", ref: <input name="name" type="text" /> }}
此处,该属性引用失败的验证类型,并且该属性包含本机 DOM input 元素。type
ref
您还可以通过将字符串而不是布尔值传递给 validation 属性来包含字段的自定义错误消息:
// ...<form onSubmit={handleSubmit(handleRegistration, handleError)}> <div> <label>Name</label> <input name="name" {...register('name', { required: "Name is required" } )} /> </div></form>
然后,使用 Hook 访问 errors 对象:useForm
const { register, handleSubmit, formState: { errors } } = useForm();
您可以向用户显示错误,如下所示:
const RegisterForm = () => { const { register, handleSubmit, formState: { errors } } = useForm(); const handleRegistration = (data) => console.log(data); return ( <form onSubmit={handleSubmit(handleRegistration)}> <div> <label>Name</label> <input type="text" name="name" {...register('name')} /> {errors?.name && errors.name.message} </div> {/* more input fields... */} <button>Submit</button> </form> );};
您可以在下面找到完整的示例:
import React from "react";import { useForm } from "react-hook-form";const RegisterForm = () => { const { register, handleSubmit, formState: { errors } } = useForm(); const handleRegistration = (data) => console.log(data); const handleError = (errors) => {}; const registerOptions = { name: { required: "Name is required" }, email: { required: "Email is required" }, password: { required: "Password is required", minLength: { value: 8, message: "Password must have at least 8 characters" } } }; return ( <form onSubmit={handleSubmit(handleRegistration, handleError)}> <div> <label>Name</label> <input name="name" type="text" {...register('name', registerOptions.name) }/> <small className="text-danger"> {errors?.name && errors.name.message} </small> </div> <div> <label>Email</label> <input type="email" name="email" {...register('email', registerOptions.email)} /> <small className="text-danger"> {errors?.email && errors.email.message} </small> </div> <div> <label>Password</label> <input type="password" name="password" {...register('password', registerOptions.password)} /> <small className="text-danger"> {errors?.password && errors.password.message} </small> </div> <button>Submit</button> </form> );};export default RegisterForm;
如果你想在有 or 事件时验证字段,你可以将属性传递给 Hook:onChange