React Hook Form 是一个高性能、灵活的 React 表单库,它利用 React Hooks 简化表单管理和验证。
1. 基本用法
安装
npm install react-hook-form
简单表单示例
import { useForm } from "react-hook-form";
function BasicForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const onSubmit = (data) => {
console.log(data); // 表单数据
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* 输入字段注册 */}
<input
{...register("username", {
required: "用户名必填",
minLength: { value: 3, message: "至少3个字符" },
})}
/>
{errors.username && <p>{errors.username.message}</p>}
<input type="password" {...register("password", { required: true })} />
{errors.password && <p>密码必填</p>}
<button type="submit">提交</button>
</form>
);
}
2. 核心 API
useForm()
| 初始化表单控制,返回表单方法register(name, rules)
| 注册表单字段(绑定验证规则)handleSubmit(callback)
| 处理表单提交,验证通过后执行回调formState.errors
| 包含字段错误信息watch()
| 监听字段变化(类似 Vue 的v-model
)reset()
| 重置表单字段
3. 验证规则示例
<input
{...register("email", {
required: "邮箱必填",
pattern: {
value: /^\S+@\S+$/i,
message: "无效的邮箱格式",
},
})}
/>
支持的内置验证:
required
:必填min
/max
:数字范围minLength
/maxLength
:长度限制pattern
:正则表达式validate
:自定义验证函数
4. 高级用法
自定义组件集成(如 Material-UI)
import { TextField } from "@mui/material";
<TextField
label="邮箱"
{...register("email")}
error={!!errors.email}
helperText={errors.email?.message}
/>;
动态表单字段
const { fields, append, remove } = useFieldArray({
control,
name: "todos",
});
{
fields.map((item, index) => (
<div key={item.id}>
<input {...register(`todos.${index}.title`)} />
<button onClick={()=> remove(index)}>删除</button>
</div>
));
}
<button onClick={()=> append({ title: "" })}>添加条目</button>;
表单状态管理
const { isDirty, isValid, isSubmitting } = formState;
<button type="submit" disabled={!isDirty || !isValid || isSubmitting}>
{isSubmitting ? "提交中..." : "提交"}
</button>;
5. 性能优化
- 减少重渲染:默认只重新渲染受影响的字段(而非整个表单)
- 按需验证:通过
mode
配置验证时机:useForm({ mode: "onChange" }); // 可选:onBlur | onSubmit | onChange
6. 与 UI 库集成示例
与 Ant Design 结合
import { Form, Input, Button } from "antd";
<Form onFinish={handleSubmit(onSubmit)}>
<Form.Item
validateStatus={errors.username ? "error" : ""}
help={errors.username?.message}
>
<Input {...register("username", { required: true })} />
</Form.Item>
</Form>;
7. 类型安全(TypeScript)
interface FormData {
username: string;
age: number;
}
const { register, handleSubmit } = useForm<FormData>();
// 字段注册时会自动推断类型
<input {...register("username")} />
<input {...register("age", { valueAsNumber: true })} />
最佳实践
-
对复杂表单使用
useFieldArray
管理动态字段 -
优先使用
onBlur
或onChange
模式提升用户体验 -
通过
resolver
集成外部验证库(如 Yup 或 Zod):import { yupResolver } from "@hookform/resolvers/yup"; import * as yup from "yup"; const schema = yup.object().shape({ username: yup.string().required(), }); useForm({ resolver: yupResolver(schema) });
React Hook Form 的轻量级设计(压缩后仅约 9KB)使其成为替代 Formik 或 Redux-Form 的高性能选择。