0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React Hook FormとZod

Posted at

はじめに

React学習のアウトプットで、React Hook FormとZodについてまとめる。

React Hook Formとは

概要

Reactのための軽量で高パフォーマンスなフォーム管理ライブラリ。
フォームの状態管理やバリデーションを簡潔に実装できる。

特徴

  1. フォーム状態の自動管理
    • 入力値、エラー状態、バリデーションの状態を内部で効率的に管理
    • 開発者が状態を手動で設定する必要がない
  2. パフォーマンス
    • 入力フィールドの状態管理が個別に行われるため、全体の再レンダリングを最小限に抑える
    • 特に、大規模なフォームでパフォーマンスの違いが顕著
  3. 柔軟なバリデーション
    • React Hook Form自体でシンプルなバリデーション(例: 必須チェック)をサポート
    • 外部バリデーションライブラリ(e.g., Zod, Yup)と統合することで、高度なバリデーションも可能
  4. 軽量
    • サイズが小さく、依存関係が少ないため、パフォーマンスへの影響が少ない

Zodとは

概要

スキーマ定義とバリデーションを行うためのTypeScript対応ライブラリ。
スキーマをもとに入力データを検証し、型安全なプログラミングを可能にする。

特徴

  1. スキーマ定義とバリデーション
    • Zodを使って、データの構造(スキーマ)とルールを定義可能
      • 例: ユーザー名は文字列、メールは有効な形式、など
  2. TypeScriptと統合
    • スキーマから型を自動生成できるため、型定義の重複を防止
    • フォームデータの型安全性を高める
  3. 柔軟で強力なバリデーション
    • 入力値に対して簡単な条件(必須、最大文字数など)から複雑なルールまで適用可能
  4. 簡単なAPI
    • シンプルな構文でスキーマを作成でき、直感的に使える

React Hook Form × Zodの連携

React Hook Formのフォーム管理機能とZodの強力なバリデーション機能を組み合わせることで、型安全で高パフォーマンスなフォームを実現することができる

連携の流れ

  1. スキーマ定義
    • Zodで入力フィールドのバリデーションルールを定義
  2. Zodをresolverとして設定
    • React Hook FormのuseFormzodResolverを指定し、Zodのバリデーションを統合
  3. フォームの送信時にバリデーションを実行
    • Zodが定義されたスキーマを使い、入力値を検証
    • エラー時はReact Hook Formがエラー状態を管理

連携のメリット

  1. 型安全性
    • フォームデータの型定義とバリデーションルールが同期
  2. 簡潔なコード
    • フォーム管理とバリデーションを分離しつつ統合的に運用
  3. 拡張性
    • 大規模プロジェクトでも柔軟に対応可能

実際に使ってみる

今回使用する技術

  • React 18
  • TypeScript
  • Vite
  • Zod
  • @hookform/resolvers

プロジェクトのセットアップ

1-1. Viteプロジェクトの作成

npm create vite@latest my-form-app --template react-ts
cd my-react18-app

1-2. React 18をインストール

npm install react@18 react-dom@18

1-3. 必要な依存関係をインストール

npm install react-hook-form @hookform/resolvers zod

フォームを実装

今回は3つの入力フォームを用意する。

import React from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";

// Zodスキーマを定義
const schema = z.object({
  username: z.string().min(3, { message: "ユーザー名は3文字以上で入力してください" }),
  email: z.string().email({ message: "有効なメールアドレスを入力してください" }),
  password: z.string().min(6, { message: "パスワードは6文字以上で入力してください" }),
});

// 型を自動生成
type FormData = z.infer<typeof schema>;

function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormData>({
    resolver: zodResolver(schema),
  });

  const onSubmit = (data: FormData) => {
    console.log("送信されたデータ:", data);
  };

  return (
    <div style={{ maxWidth: "400px", margin: "0 auto", fontFamily: "Arial, sans-serif" }}>
      <h1>フォーム入力</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        {/* ユーザー名 */}
        <div>
          <label>ユーザー名:</label>
          <input {...register("username")} />
          {errors.username && <p style={{ color: "red" }}>{errors.username.message}</p>}
        </div>

        {/* メールアドレス */}
        <div>
          <label>メールアドレス:</label>
          <input type="email" {...register("email")} />
          {errors.email && <p style={{ color: "red" }}>{errors.email.message}</p>}
        </div>

        {/* パスワード */}
        <div>
          <label>パスワード:</label>
          <input type="password" {...register("password")} />
          {errors.password && <p style={{ color: "red" }}>{errors.password.message}</p>}
        </div>

        <button type="submit" style={{ marginTop: "10px" }}>送信</button>
      </form>
    </div>
  );
}

export default App;

開発サーバーを起動

以下のコマンドを実行してアプリケーションを起動。

npm run dev

動作確認

  1. 正常な入力
    • フィールドに正しい値を入力し、「送信」ボタンを押すと、コンソールにフォームデータが出力される
{
  "username": "testuser",
  "email": "test@example.com",
  "password": "password123"
}
  1. 不正な入力
    • バリデーションエラーが発生すると、各フィールドの下にエラーメッセージが表示される

Tips:リアルタイムでバリデーションを行うには

useFormmodeオプションを変更する。

const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm<FormData>({
  resolver: zodResolver(schema),
  mode: "onChange", // 入力中にバリデーションを行う
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?