安装
安装 React Hook Form 只需一个命令,你就可以开始使用了。
¥Installing React Hook Form only takes a single command and you're ready to roll.
npm install react-hook-form
示例
¥Example
以下代码摘录演示了一个基本用法示例:
¥The following code excerpt demonstrates a basic usage example:
import { useForm, SubmitHandler } from "react-hook-form"type Inputs = {example: stringexampleRequired: string}export default function App() {const {register,handleSubmit,watch,formState: { errors },} = useForm<Inputs>()const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data)console.log(watch("example")) // watch input value by passing the name of itreturn (/* "handleSubmit" will validate your inputs before invoking "onSubmit" */<form onSubmit={handleSubmit(onSubmit)}>{/* register your input into the hook by invoking the "register" function */}<input defaultValue="test" {...register("example")} />{/* include validation with required or other standard HTML validation rules */}<input {...register("exampleRequired", { required: true })} />{/* errors will return when field validation fails */}{errors.exampleRequired && <span>This field is required</span>}<input type="submit" /></form>)}
React 网络视频教程
本视频教程说明了 React Hook Form 的基本用法和概念。
¥This video tutorial illustrates the basic usage and concepts of React Hook Form.
注册字段
React Hook Form 中的关键概念之一是将你的组件 register
放入钩子中。这将使其值可用于表单验证和提交。
¥One of the key concepts in React Hook Form is to register
your component into the hook. This will make its value available for both the form validation and submission.
注意:每个字段都需要有一个 name
作为注册过程的密钥。
¥Note: Each field is required to have a name
as a key for the registration process.
import ReactDOM from "react-dom"import { useForm, SubmitHandler } from "react-hook-form"enum GenderEnum {female = "female",male = "male",other = "other",}interface IFormInput {firstName: stringgender: GenderEnum}export default function App() {const { register, handleSubmit } = useForm<IFormInput>()const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><label>First Name</label><input {...register("firstName")} /><label>Gender Selection</label><select {...register("gender")}><option value="female">female</option><option value="male">male</option><option value="other">other</option></select><input type="submit" /></form>)}
应用验证
React Hook Form 通过与现有的 表单验证的 HTML 标准 保持一致,使表单验证变得容易。
¥React Hook Form makes form validation easy by aligning with the existing HTML standard for form validation.
支持的验证规则列表:
¥List of validation rules supported:
-
required
-
min
-
max
-
minLength
-
maxLength
-
pattern
-
validate
你可以在 注册章节 中阅读有关每条规则的更多详细信息。
¥You can read more detail on each rule in the register section.
import { useForm, SubmitHandler } from "react-hook-form"interface IFormInput {firstName: stringlastName: stringage: number}export default function App() {const { register, handleSubmit } = useForm<IFormInput>()const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input {...register("firstName", { required: true, maxLength: 20 })} /><input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} /><input type="number" {...register("age", { min: 18, max: 99 })} /><input type="submit" /></form>)}
整合现有表单
集成现有表单应该很简单。重要的一步是 register
组件的 ref
并将相关属性分配给你的输入。
¥Integrating an existing form should be simple. The important step is to register
the component's ref
and assign relevant props to your input.
import { Path, useForm, UseFormRegister, SubmitHandler } from "react-hook-form"interface IFormValues {"First Name": stringAge: number}type InputProps = {label: Path<IFormValues>register: UseFormRegister<IFormValues>required: boolean}// The following component is an example of your existing Input Componentconst Input = ({ label, register, required }: InputProps) => (<><label>{label}</label><input {...register(label, { required })} /></>)// you can use React.forwardRef to pass the ref tooconst Select = React.forwardRef<HTMLSelectElement,{ label: string } & ReturnType<UseFormRegister<IFormValues>>>(({ onChange, onBlur, name, label }, ref) => (<><label>{label}</label><select name={name} ref={ref} onChange={onChange} onBlur={onBlur}><option value="20">20</option><option value="30">30</option></select></>))const App = () => {const { register, handleSubmit } = useForm<IFormValues>()const onSubmit: SubmitHandler<IFormValues> = (data) => {alert(JSON.stringify(data))}return (<form onSubmit={handleSubmit(onSubmit)}><Input label="First Name" register={register} required /><Select label="Age" {...register("Age")} /><input type="submit" /></form>)}
整合 UI 库
React Hook Form 可以轻松地与外部 UI 组件库集成。如果组件不公开输入的 ref
,那么你应该使用 控制器 组件,它将负责注册过程。
¥React Hook Form has made it easy to integrate with external UI component libraries. If the component doesn't expose input's ref
, then you should use the Controller component, which will take care of the registration process.
import Select from "react-select"import { useForm, Controller, SubmitHandler } from "react-hook-form"import { Input } from "@material-ui/core"interface IFormInput {firstName: stringlastName: stringiceCreamType: { label: string; value: string }}const App = () => {const { control, handleSubmit } = useForm({defaultValues: {firstName: "",lastName: "",iceCreamType: {},},})const onSubmit: SubmitHandler<IFormInput> = (data) => {console.log(data)}return (<form onSubmit={handleSubmit(onSubmit)}><Controllername="firstName"control={control}render={({ field }) => <Input {...field} />}/><Controllername="iceCreamType"control={control}render={({ field }) => (<Select{...field}options={[{ value: "chocolate", label: "Chocolate" },{ value: "strawberry", label: "Strawberry" },{ value: "vanilla", label: "Vanilla" },]}/>)}/><input type="submit" /></form>)}
整合受控输入
该库包含不受控制的组件和原生 HTML 输入。然而,很难避免使用外部受控组件,例如 反应选择、AntD 和 MUI。为了简化这一过程,我们提供了一个封装器组件 控制器,以简化集成过程,同时仍然让你可以自由地使用自定义注册。
¥This library embraces uncontrolled components and native HTML inputs. However, it's hard to avoid working with external controlled components such as React-Select, AntD and MUI. To make this simple, we provide a wrapper component, Controller, to streamline the integration process while still giving you the freedom to use a custom register.
使用组件 API
¥Using Component API
import { useForm, Controller, SubmitHandler } from "react-hook-form"import { TextField, Checkbox } from "@material-ui/core"interface IFormInputs {TextField: stringMyCheckbox: boolean}function App() {const { handleSubmit, control, reset } = useForm<IFormInputs>({defaultValues: {MyCheckbox: false,},})const onSubmit: SubmitHandler<IFormInputs> = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><Controllername="MyCheckbox"control={control}rules={{ required: true }}render={({ field }) => <Checkbox {...field} />}/><input type="submit" /></form>)}
使用钩子 API
¥Using Hooks API
import * as React from "react"import { useForm, useController, UseControllerProps } from "react-hook-form"type FormValues = {FirstName: string}function Input(props: UseControllerProps<FormValues>) {const { field, fieldState } = useController(props)return (<div><input {...field} placeholder={props.name} /><p>{fieldState.isTouched && "Touched"}</p><p>{fieldState.isDirty && "Dirty"}</p><p>{fieldState.invalid ? "invalid" : "valid"}</p></div>)}export default function App() {const { handleSubmit, control } = useForm<FormValues>({defaultValues: {FirstName: "",},mode: "onChange",})const onSubmit = (data: FormValues) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><Input control={control} name="FirstName" rules={{ required: true }} /><input type="submit" /></form>)}
整合全局状态
该库不需要你依赖状态管理库,但你可以轻松地与它们集成。
¥This library doesn't require you to rely on a state management library, but you can easily integrate with them.
import { useForm } from "react-hook-form"import { connect } from "react-redux"import updateAction from "./actions"export default function App(props) {const { register, handleSubmit, setValue } = useForm({defaultValues: {firstName: "",lastName: "",},})// Submit your data into Redux storeconst onSubmit = (data) => props.updateAction(data)return (<form onSubmit={handleSubmit(onSubmit)}><input {...register("firstName")} /><input {...register("lastName")} /><input type="submit" /></form>)}// Connect your component with reduxconnect(({ firstName, lastName }) => ({ firstName, lastName }),updateAction)(YourForm)
处理错误
React Hook Form 提供了一个 errors
对象来显示表单中的错误。errors
的类型将返回给定的验证约束。以下示例展示了所需的验证规则。
¥React Hook Form provides an errors
object to show you the errors in the form. errors
' type will return given validation constraints. The following example showcases a required validation rule.
import { useForm } from "react-hook-form"export default function App() {const {register,formState: { errors },handleSubmit,} = useForm()const onSubmit = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input{...register("firstName", { required: true })}aria-invalid={errors.firstName ? "true" : "false"}/>{errors.firstName?.type === "required" && (<p role="alert">First name is required</p>)}<input{...register("mail", { required: "Email Address is required" })}aria-invalid={errors.mail ? "true" : "false"}/>{errors.mail && <p role="alert">{errors.mail.message}</p>}<input type="submit" /></form>)}
整合服务
要将 React Hook Form 与服务集成,你可以使用该库的内置提交处理。<Form />
组件允许你轻松地将表单数据发送到 API 端点或其他服务。了解有关表单组件的更多信息。
¥To integrate React Hook Form with a service, you can use the library's built-in submission handling. <Form />
component allow you to easily send form data to an API endpoint or other service. Find out more about Form component.
import { Form } from "react-hook-form"function App() {const { register, control } = useForm()return (<Formaction="/api/save" // Send post request with the FormData// encType={'application/json'} you can also switch to json objectonSuccess={() => {alert("Your application is updated.")}}onError={() => {alert("Submission has failed.")}}control={control}><input {...register("firstName", { required: true })} /><input {...register("lastName", { required: true })} /><button>Submit</button></Form>)}
模式验证
我们还支持使用 Yup、Zod、Superstruct 和 Joi 进行基于模式的表单验证,你可以将 schema
传递到 useForm 作为可选配置。它将根据架构验证你的输入数据,并返回 错误 或有效结果。
¥We also support schema-based form validation with Yup, Zod , Superstruct & Joi, where you can pass your schema
to useForm as an optional config. It will validate your input data against the schema and return with either errors or a valid result.
步骤 1:将 Yup
安装到你的项目中。
¥Step 1: Install Yup
into your project.
npm install @hookform/resolvers yup
第 2 步:准备你的模式以进行验证并使用 React Hook Form 注册输入。
¥Step 2: Prepare your schema for validation and register inputs with React Hook Form.
import { useForm } from "react-hook-form"import { yupResolver } from "@hookform/resolvers/yup"import * as yup from "yup"const schema = yup.object({firstName: yup.string().required(),age: yup.number().positive().integer().required(),}).required()export default function App() {const {register,handleSubmit,formState: { errors },} = useForm({resolver: yupResolver(schema),})const onSubmit = (data) => console.log(data)return (<form onSubmit={handleSubmit(onSubmit)}><input {...register("firstName")} /><p>{errors.firstName?.message}</p><input {...register("age")} /><p>{errors.age?.message}</p><input type="submit" /></form>)}
React Native
你将在 React Native 中获得相同的性能提升和增强。要与输入组件集成,可以用 Controller
封装它。
¥You will get the same performance boost and enhancement in React Native. To integrate with input component, you can wrap it with Controller
.
import { Text, View, TextInput, Button, Alert } from "react-native"import { useForm, Controller } from "react-hook-form"export default function App() {const {control,handleSubmit,formState: { errors },} = useForm({defaultValues: {firstName: "",lastName: "",},})const onSubmit = (data) => console.log(data)return (<View><Controllercontrol={control}rules={{required: true,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="First name"onBlur={onBlur}onChangeText={onChange}value={value}/>)}name="firstName"/>{errors.firstName && <Text>This is required.</Text>}<Controllercontrol={control}rules={{maxLength: 100,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="Last name"onBlur={onBlur}onChangeText={onChange}value={value}/>)}name="lastName"/><Button title="Submit" onPress={handleSubmit(onSubmit)} /></View>)}
TypeScript
React Hook Form 使用 TypeScript
构建,你可以定义 FormData
类型来支持表单值。
¥React Hook Form is built with TypeScript
, and you can define a FormData
type to support form values.
import * as React from "react"import { useForm } from "react-hook-form"type FormData = {firstName: stringlastName: string}export default function App() {const {register,setValue,handleSubmit,formState: { errors },} = useForm<FormData>()const onSubmit = handleSubmit((data) => console.log(data))// firstName and lastName will have correct typereturn (<form onSubmit={onSubmit}><label>First Name</label><input {...register("firstName")} /><label>Last Name</label><input {...register("lastName")} /><buttontype="button"onClick={() => {setValue("lastName", "luo") // ✅setValue("firstName", true) // ❌: true is not stringerrors.bill // ❌: property bill does not exist}}>SetValue</button></form>)}
设计与理念
React Hook Form 的设计和理念注重用户和开发者体验。该库旨在通过微调性能和提高可访问性来为用户提供更流畅的交互体验。一些性能增强包括:
¥React Hook Form's design and philosophy focus on user and developer experience. The library aims to provide users with a smoother interaction experience by fine-tuning the performance and improving accessibility. Some of the performance enhancements include:
-
通过代理引入表单状态订阅模型
¥Introducing form state subscription model through the proxy
-
避免不必要的计算
¥Avoiding unnecessary computation
-
需要时隔离组件重新渲染
¥Isolating component re-rendering when required
总的来说,它改善了用户与应用交互时的用户体验。对于开发者来说,我们引入了内置验证,并与 HTML 标准紧密结合,允许通过强大的验证方法进一步扩展并与原生模式验证集成。此外,在 TypeScript 的帮助下拥有经过严格类型检查的表单可以提供早期构建时反馈,以帮助和指导开发者构建强大的表单解决方案。
¥Overall, it improves the user experience while users interact with the application. As for the developers, we introduce built-in validation and are closely aligned with HTML standards allowing further extension with powerful validation methods and integration with schema validation natively. In addition, having a strongly type-checked form with the help of typescript provides early build-time feedback to help and guide the developer to build a robust form solution.
Bill 的以下演讲展示了一些想法和设计模式:
¥The following talk given by Bill showcased some of the ideas and design patterns: