📖

react-hook-form基礎

2024/08/23に公開

react-hook-formとは?

react-hook-formとは、フォームのバリデーションチェックを簡単に行えるツールです。
以下のコマンドで簡単にインストールして使用することができます。また、zodといったスキーマ(構造)を定義するツールを使用することで、フォームのデータ構造をシンプルかつ安全に定義できます。

npm i react-hook-form 

基本的な使用方法

1. 全体コード

コードは以下の通りです。順を追って、詳細を説明します。

"use client";
import React from "react";
import { useForm } from "react-hook-form";
const HookFrom = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    defaultValues: {
      firstName: "",
      lastName: "",
      email: "",
    },
  });
  // formState: { errors }とすることで、registerで指定した要素にmessageプロパティが追加され、errorメッセージが記入できるようになる
  console.log(errors);
  const onSubmit = (data: any) => {
    console.log("onSubmit", data);
  };
  return (
    <div className="flex justify-center items-center h-screen bg-green-100">
      <form
        className="w-full max-w-md bg-white p-8 rounded-lg shadow-lg"
        onSubmit={handleSubmit(onSubmit)}
      >
        <h2 className="text-2xl font-bold mb-6 text-gray-800 text-center">
          react-hook-form
        </h2>

        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2">
            firstName
          </label>
          <input
            {...register("firstName", { required: "入力は必須です" })}
            // registerは、useFormに値を監視させるためのメソッド,inputのname属性に対して付与することで、ここで入力された値を監視する、
            // handleSubmit内にonSubmitで、入力フォームをconsoleに表示する処理を記述することで、フォームの入力内容を確認できる。
            // requiredは、そのフォームが入力必須か否かを指定するもので、trueにすると必須となり、空の状態で送信しようとするとそのinputタグにフォーカスが当たる。

            type="text"
            className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
          />
          <p>{errors.firstName?.message}</p>
        </div>

        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2">
            lastName
          </label>
          <input
            {...register("lastName", {
              required: "入力は必須です",
              minLength: {
                value: 4,
                message: "4文字以上で入力してください",
              },
            })}
            type="text"
            className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
          />
          <p>{errors.lastName?.message}</p>
        </div>

        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2">
            email
          </label>
          <input
            {...register("email", {
              required: "入力は必須です",
            })}
            type="text"
            className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
          />
          <p>{errors.email?.message}</p>
        </div>

        <button
          type="submit"
          className="w-full bg-green-500 text-white p-3 rounded hover:bg-green-600 transition duration-300"
        >
          テスト登録
        </button>
      </form>
    </div>
  );
};

export default HookFrom;

2. useFormについて

・registerは、react-hook-formにinput要素の監視を依頼し、バリデーションチェックをスムーズに行えるようにする仲介人的なメソッドです。

・handleSubmitは、フォーム送信時にバリデーションチェックを行うメソッドです。

・formStateはバリデーションチェックで発生したエラーを格納しておくオブジェクトです。

上記を呼び出して使用します。

useForm内の引数に指定しているdefaultValuesのプロパティ名は、input要素内のname属性を指定しています。値はvalue属性を指します。初期値を空文字にしていますが、任意で値を指定することも可能です。

const {
 register,
 handleSubmit,
 formState: { errors },
} = useForm({
 defaultValues: {
   firstName: "",
   lastName: "",
   email: "",
 },

3.form内の記述

registerはスプレッド構文を使用して記述し、"firstName"の部分は、input要素のname属性です。一意に指定して下さい

requiredは、そのフォームが入力必須か否かを指定します。以下のように指定することで、フォームの入力が必須になり、空で送信しようとすると、そのinput要素にフォーカスが当たります。

{required :true}

メッセ―ジを指定したい場合は、trueの部分を任意のメッセージに置換することで、メッセージを出力できます。
出力したい部分に以下を埋め込むことで、表示できます。

  <p>{errors.firstName?.message}</p>

文字数制限を書けることも可能です。今回は最小文字数ですが、最大文字列を指定することも可能です。

・valueは4文字以上という意味です。valueがfalseを返した場合に、messageが出力されます。

   minLength: {
                value: 4,
                message: "4文字以上で入力してください",
              }
 <div className="flex justify-center items-center h-screen bg-green-100">
      <form
        className="w-full max-w-md bg-white p-8 rounded-lg shadow-lg"
        onSubmit={handleSubmit(onSubmit)}
      >
        <h2 className="text-2xl font-bold mb-6 text-gray-800 text-center">
          react-hook-form
        </h2>

        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2">
            firstName
          </label>
          <input
            {...register("firstName", { required: "入力は必須です" })}
            type="text"
            className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
          />
          <p>{errors.firstName?.message}</p>
        </div>

        <div className="mb-4">
          <label className="block text-gray-700 text-sm font-bold mb-2">
            lastName
          </label>
          <input
            {...register("lastName", {
              required: "入力は必須です",
              minLength: {
                value: 4,
                message: "4文字以上で入力してください",
              },
            })}
            type="text"
            className="w-full p-3 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-green-500"
          />
          <p>{errors.lastName?.message}</p>
        </div>

   <button
          type="submit"
          className="w-full bg-green-500 text-white p-3 rounded hover:bg-green-600 transition duration-300"
        >
          テスト登録
        </button>
      </form>
    </div>

まとめ

かなり雑な説明になってしまいましたが基本的な使用方法は以上です。入力の値を常に監視するwatchメソッドなどもあるようなので、詳細はドキュメントを読んでみてください。

zodを使用したものは、別の記事で書こうと思います。

https://react-hook-form.com/get-started#Registerfields

Discussion