React Hook Form (RHF) 详细介绍
December 6, 2024
React Hook Form (RHF) 是一个用于构建 React 表单的轻量级库,其核心目标是简化表单的状态管理和验证,同时提高性能。以下是对 React Hook Form 的详细介绍,包括其特点、基本用法以及进阶功能。
1. React Hook Form 的核心特点
-
轻量高效:
- 基于非受控组件设计,减少了组件的重新渲染。
- 与受控组件相比,大幅降低性能消耗。
-
简单易用:
- 基于 React Hooks,无需引入复杂的上下文或状态管理。
-
灵活验证:
- 内置多种验证机制,并支持与验证库(如 Yup)集成。
-
类型安全:
- 提供 TypeScript 支持,确保表单类型安全。
2. 核心 API
2.1. useForm
useForm
是 RHF 的核心钩子,用于管理表单状态。
常用配置选项:
defaultValues
:设置初始值。mode
:验证触发模式(如onChange
,onBlur
,onSubmit
)。resolver
:用于集成外部验证库(如 Yup)。
示例:
import { useForm } from 'react-hook-form';
function App() {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("username", { required: true })} placeholder="Username" />
{errors.username && <span>Username is required</span>}
<input type="submit" />
</form>
);
}
2.2. register
- 用于将输入元素注册到 RHF。
- 接收字段名称和校验规则。
常见校验规则:
required
:是否为必填字段。minLength
/maxLength
:最小/最大字符长度。pattern
:正则表达式验证。
示例:
<input
{...register("password", {
required: "Password is required",
minLength: { value: 6, message: "Password must be at least 6 characters" }
})}
/>
2.3. handleSubmit
- 包装提交函数,用于在表单验证通过后调用回调。
- 自动拦截无效数据。
示例:
const onSubmit = (data) => {
console.log("Valid Data:", data);
};
<form onSubmit={handleSubmit(onSubmit)} />
2.4. formState
包含表单状态信息,例如:
errors
: 当前表单的验证错误。isSubmitting
: 表单是否正在提交。isDirty
: 表单值是否被修改。
2.5. watch
- 实时监控表单字段值的变化。
- 可以监控单个字段或整个表单。
示例:
const username = watch("username");
2.6. reset
和 setValue
reset
: 重置表单为默认值或指定值。setValue
: 手动设置表单字段值。
示例:
reset({ username: "JohnDoe" });
setValue("email", "john@example.com");
3. 基本用法
3.1. 简单表单
import React from 'react';
import { useForm } from 'react-hook-form';
function SimpleForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name", { required: true })} placeholder="Name" />
{errors.name && <span>Name is required</span>}
<input type="email" {...register("email", { required: true })} placeholder="Email" />
{errors.email && <span>Email is required</span>}
<button type="submit">Submit</button>
</form>
);
}
export default SimpleForm;
4. 进阶功能
4.1. 默认值
通过 useForm
的 defaultValues
设置表单的初始值。
const { register, handleSubmit } = useForm({
defaultValues: {
name: "John Doe",
email: "john@example.com",
}
});
4.2. 集成 Yup 进行验证
通过 @hookform/resolvers
将 Yup 集成到 RHF。
npm install @hookform/resolvers yup
示例:
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
const schema = Yup.object().shape({
username: Yup.string().required("Username is required"),
email: Yup.string().email("Invalid email").required("Email is required"),
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("username")} placeholder="Username" />
{errors.username && <span>{errors.username.message}</span>}
<input {...register("email")} placeholder="Email" />
{errors.email && <span>{errors.email.message}</span>}
<button type="submit">Submit</button>
</form>
);
}
4.3. 动态表单
动态添加或删除字段。
import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
function DynamicForm() {
const { register, handleSubmit } = useForm();
const [fields, setFields] = useState([{}]);
const addField = () => setFields([...fields, {}]);
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
{fields.map((_, index) => (
<input key={index} {...register(`field${index}`)} placeholder={`Field ${index + 1}`} />
))}
<button type="button" onClick={addField}>Add Field</button>
<button type="submit">Submit</button>
</form>
);
}
4.4. 与 UI 库集成
与 Material-UI、Ant Design 等库集成。
示例:Ant Design Input
import { Controller, useForm } from 'react-hook-form';
import { Input } from 'antd';
function AntdForm() {
const { control, handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="username"
control={control}
render={({ field }) => <Input {...field} placeholder="Username" />}
/>
<button type="submit">Submit</button>
</form>
);
}
5. 性能优化
- 默认优化:非受控组件减少了组件重新渲染。
useController
:对复杂场景提供更细粒度的控制。- 惰性验证:只验证用户已触摸的字段,减少性能开销。
6. 常见场景与解决方案
- 多步骤表单:通过保存每步数据到状态中实现。
- 条件渲染字段:根据条件动态添加/删除字段。
- 文件上传:通过
ref
获取文件输入并处理。
React Hook Form 提供了强大的功能和高效的性能,是构建现代 React 表单的首选工具之一。