Docs
React Hook Form
React Hook Form
React Hook FormとZodを使用したフォームの構築.
フォームは扱いが難しいものです。それはウェブアプリケーションにおいて最も一般的に作成するものの1つですが、最も複雑なものの一つでもあります。
適切に設計されたHTMLフォームは:
- 構造化が良く、セマンティックに正しい。
- 使いやすくナビゲートしやすい(キーボード)。
- ARIA属性と適切なラベルでアクセシビリティがある。
- クライアント側とサーバー側のバリデーションをサポートしている。
- スタイルが良く、アプリケーションの他の部分と一貫している。
このガイドではreact-hook-form
とzod
を使用してフォームを構築します。 Radix UIコンポーネントを使用して、アクセシビリティのあるフォームを構成するために <FormField>
コンポーネントを使用する予定です。
機能
<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>
)}
/>
インストール
使用
フォームスキーマの作成
Zodスキーマを使用してフォームの形状を定義します。 Zodの使用の詳細については、Zodのドキュメントをご覧ください。
"use client"
import { z } from "zod"
const formSchema = z.object({
username: z.string().min(2).max(50),
})
フォームの定義
react-hook-form
のuseForm
フックを使用して、フォームを作成します。
"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>
)
}
完了
これで、クライアント側のバリデーションがタイプセーフで、完全にアクセシビリティのあるフォームができました。
例
他のコンポーネントと一緒に<Form />
コンポーネントを使用する方法に関する詳細については、次のリンクを参照してください。