Docs
React Hook Form

React Hook Form

使用 React Hook Form 和 Zod 构建表单。

表单是棘手的。它们是您在 web 应用程序中构建的最常见的元素之一,但也是最复杂的元素之一。

设计良好的 HTML 表单应该具备:

  • 构造良好且语义正确。
  • 易于使用和导航(键盘)。
  • 通过 ARIA 属性和适当的标签可访问。
  • 支持客户端和服务器端验证。
  • 风格良好,并与应用程序的其余部分保持一致。

在本指南中,我们将探讨如何使用 react-hook-formzod 构建表单。我们将使用 <FormField> 组件组合可访问的表单,使用 Radix UI 组件。

特性

<Form /> 组件是对 react-hook-form 库的封装。它提供了一些功能:

  • 用于构建表单的可组合组件。
  • 一个用于构建受控表单字段的 <FormField /> 组件。
  • 使用 zod 进行表单验证。
  • 处理可访问性和错误消息。
  • 使用 React.useId() 生成唯一 ID。
  • 根据状态将正确的 aria 属性应用于表单字段。
  • 建造与所有 Radix UI 组件兼容。
  • 自带模式库。我们使用 zod,但您可以使用任何您想要的。
  • 您对标记和样式有完全的控制权。

组成部分

<Form>
  <FormField
    control={...}
    name="..."
    render={() => (
      <FormItem>
        <FormLabel />
        <FormControl>
          { /* 您的表单字段 */}
        </FormControl>
        <FormDescription />
        <FormMessage />
      </FormItem>
    )}
  />
</Form>

示例

const form = useForm()
 
<FormField
  control={form.control}
  name="username"
  render={({ field }) => (
    <FormItem>
      <FormLabel>用户名</FormLabel>
      <FormControl>
        <Input placeholder="shadcn" {...field} />
      </FormControl>
      <FormDescription>这是您的公开显示名称。</FormDescription>
      <FormMessage />
    </FormItem>
  )}
/>

安装

命令

pnpm dlx shadcn@latest add form

用法

创建表单模式

使用 Zod 模式定义表单的形状。您可以在 Zod 文档 中了解有关使用 Zod 的更多信息。

"use client"
 
import { z } from "zod"
 
const formSchema = z.object({
  username: z.string().min(2).max(50),
})

定义表单

使用 react-hook-formuseForm 钩子创建一个表单。

"use client"
 
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
 
const formSchema = z.object({
  username: z.string().min(2, {
    message: "用户名必须至少为 2 个字符。",
  }),
})
 
export function ProfileForm() {
  // 1. 定义您的表单。
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      username: "",
    },
  })
 
  // 2. 定义提交处理程序。
  function onSubmit(values: z.infer<typeof formSchema>) {
    // 使用表单值执行操作。
    // ✅ 这将是类型安全和经过验证的。
    console.log(values)
  }
}

由于 FormField 使用的是受控组件,您需要为字段提供默认值。请参阅 React Hook Form 文档 了解有关受控组件的更多信息。

构建表单

现在我们可以使用 <Form /> 组件来构建我们的表单。

"use client"
 
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
 
import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
 
const formSchema = z.object({
  username: z.string().min(2, {
    message: "用户名必须至少为 2 个字符。",
  }),
})
 
export function ProfileForm() {
  // ...
 
  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
        <FormField
          control={form.control}
          name="username"
          render={({ field }) => (
            <FormItem>
              <FormLabel>用户名</FormLabel>
              <FormControl>
                <Input placeholder="shadcn" {...field} />
              </FormControl>
              <FormDescription>
                这是您的公开显示名称。
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">提交</Button>
      </form>
    </Form>
  )
}

完成

就这样。您现在拥有一个完全可访问、类型安全且具有客户端验证的表单。

This is your public display name.

示例

有关如何将 <Form /> 组件与其他组件一起使用的更多示例,请参见以下链接: