在使用React进行开发的时候,如果是简单的表单还好。如果遇到复杂的表单,比如分好几个步骤的表单,联动效果的字段,多层结构的字段等等,就需要一个好的框架的支持了。下面分几篇文章系统介绍一下:React Hook Form

React Hook Form
图源:React Hook Form官网
React Hook Form官网:https://react-hook-form.com/
React Hook Form GH:https://github.com/react-hook-form/react-hook-form
React Hook Form系列
创建项目
bash
npx create-react-app demo --template typescript
cd demo
yarn add react-hook-form
React Hook Form中的几个重要函数
register
它的作用就是将表单中的某个字段注册,这样在提交的时候就能够获取该字段的值。
javascript
<input {...register('email')}/><br/>
在注册时,还能附加一些验证条件,比如:
javascript
<input {...register('email', {required: true})}/><br/>
React Hook Form支持的验证方式
在React Hook Form中,支持以下的验证方式:
- required:必填字段
- min:最小值
- max:最大值
- minLength:最小长度
- maxLength:最大长度
- pattern:通过正则表达式限定字段格式
- validate:通过事先定义好的schema进行验证,支持第三方schema,比如:Yup, Zod, SuperStruct以及Joi
handleSubmit
这个函数就是处理提交请求的,其参数就是自定义的提交处理函数:
javascript
const formSubmitHandler: SubmitHandler<IFormInputs> = (data: IFormInputs) => {
console.log(data);
}
......
<form onSubmit={handleSubmit(formSubmitHandler)}>
在自定义提交处理函数中,可以通过解构赋值来获取每个字段的值:
javascript
const { email, password } = data;
watch
可以通过以下方式来监测某个输入字段:
javascript
console.log("watching email field", watch('email'));
可以看到,每当有键盘输入的时候,以上的console.log就会作为回调函数被调用:

React Hook Form教程
formState
通过这个对象,可以监测form的状态,比如其中的出错状态可以通过errors这个属性来获取:
javascript
const { errors } = formState
...
{errors.password && <span title="Password is required." className="invalid_field">*</span>}
完整示例
javascript
import { FC } from "react";
import { useForm, SubmitHandler } from "react-hook-form";
interface IFormInputs {
firstName: string,
lastName: string,
email: string;
password: string;
}
const Test1: FC = () => {
const {
register,
handleSubmit,
//watch,
formState: { errors },
} = useForm<IFormInputs>();
const formSubmitHandler: SubmitHandler<IFormInputs> = (formdata: IFormInputs) => {
console.log(formdata);
}
return (
<div>
<form onSubmit={handleSubmit(formSubmitHandler)}>
<input {...register('firstName', {required: true, pattern: /^[A-Za-z]+$/i})}/><br/>
{errors.firstName && <span className="invalid_field">First name is required (characters only).</span>}<br/>
<input {...register('lastName', {required: true, pattern: /^[A-Za-z]+$/i})}/><br/>
{errors.lastName && <span className="invalid_field">Last name is required (characters only).</span>}<br/>
<input {...register('email', {required: true})}/><br/>
{errors.email && <span className="invalid_field">Email is required.</span>}<br/>
<input {...register('password', {required: true, minLength: 8})}/><br/>
{errors.password && <span className="invalid_field">Password is required.</span>}<br/>
<br/>
<br/>
<button type='submit'>Submit</button>
</form>
</div>
);
};
export default Test1;