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で検証機能の実装

Last updated at Posted at 2024-11-26

React Hook Formの基本機能

1. インストール&インポート

> npm install react-hook-form
# または
> yarn add react-hook-form
import { useForm } from "react-hook-form";

2. フォームの初期化

  • defaultValuesで初期値の設定
  • useFormでフォームの初期化
    • register 入力要素にハンドラーなどを登録する
    • handleSubmit サブミット時に使用する
    • formState: { errors } エラー状態を取得する
    • defaultValues 初期値を設定する
  const defaultValues = {
    name: "",
    email: "",
    gender: "male",
    country: "japan",
    agree: false,
    memo: "",
  };
  
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    defaultValues,
  });

3. FormのonSubmit設定

  • onSubmit=handleSubmit(onsubmit, onerror)
    • noValidate ブラウザによるデフォルトのフォーム入力検証を無効
  • onsubmit 検証成功時の処理
  • onerror 検証失敗時の処理
<form onSubmit={handleSubmit(onsubmit, onerror)} noValidate>
  {/* 入力要素... */}
  <button type="submit">送信</button>
</form>
const onsubmit = (data) => console.log(data);
const onerror = (err) => console.log(err);

4. 入力要素にregisterをスプレッド演算子で展開する(フィールド名, 検証ルールなど)

  • 基本 register(フィールド名)をinputタグに入れる
    • ...register("name")
  • バリデーション
    • {required: "必須メッセージ", maxLength: {value: 20, message: "文字数メッセージ"}}
  • エラー表示部分
    • {errors.name && <div>{errors.name.message}</div>}
<div>
  <label htmlFor="name">名前</label>
  <input
    id="name"
    type="text"
    // registerをスプレッド演算子で展開する(フィールド名, 検証ルールなど)
    {...register("name", {
      required: "名前は必須入力です。",
      maxLength: {
        value: 20,
        message: "名前は20文字以内にしてください",
      },
    })}
  />
  {errors.name && <div>{errors.name.message}</div>}
</div>

ソース全体

import { useForm } from "react-hook-form";

export default function FormBasic() {
  const defaultValues = {
    name: "",
    email: "",
    gender: "male",
    country: "japan",
    agree: false,
    memo: "",
  };

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    defaultValues,
  });

  const onSubmit = (data) => console.log(data);
  const onError = (errors) => console.log(errors);

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit, onError)} noValidate>
        <div>
          <label htmlFor="name">名前</label>
          <input
            id="name"
            type="text"
            {...register("name", {
              required: "名前は必須入力です。",
              maxLength: {
                value: 20,
                message: "名前は20文字以内にしてください",
              },
            })}
          />
          {errors.name && <div role="alert">{errors.name.message}</div>}
        </div>
        <div>
          <label htmlFor="gender">性別</label>
          <div>
            <label>
              <input
                type="radio"
                value="male"
                {...register("gender", {
                  required: "性別は必須です。",
                })}
              />
              男性
            </label>
            <label>
              <input
                type="radio"
                value="female"
                {...register("gender", {
                  required: "性別は必須です。",
                })}
              />
              女性
            </label>
          </div>
          {errors.gender && <div role="alert">{errors.gender.message}</div>}
        </div>
        <div>
          <label htmlFor="country">国籍</label>
          <select
            id="country"
            {...register("country", {
              required: "国籍を選択してください。",
            })}
          >
            <option value="">選択してください</option>
            <option value="japan">日本</option>
            <option value="usa">アメリカ</option>
            <option value="china">中国</option>
            <option value="other">その他</option>
          </select>
          {errors.country && <div role="alert">{errors.country.message}</div>}
        </div>
        <div>
          <label htmlFor="email">メールアドレス</label>
          <input
            id="email"
            type="email"
            {...register("email", {
              required: "メールアドレスは必須入力です。",
              pattern: {
                value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
                message: "メールアドレスの形式が不正です。",
              },
            })}
          />
          {errors.email && <div role="alert">{errors.email.message}</div>}
        </div>
        <div>
          <label htmlFor="agree">
            <input
              id="agree"
              type="checkbox"
              {...register("agree", {
                required: "利用規約に同意してください。",
              })}
            />
            利用規約に同意する
          </label>
          {errors.agree && <div role="alert">{errors.agree.message}</div>}
        </div>
        <div>
          <label htmlFor="memo">備考</label>
          <textarea
            id="memo"
            {...register("memo", {
              required: "備考は必須入力です。",
              minLength: {
                value: 10,
                message: "備考は10文字以上にしてください",
              },
            })}
          />
          {errors.memo && <div role="alert">{errors.memo.message}</div>}
        </div>
        <div>
          <button type="submit">送信</button>
        </div>
      </form>
    </div>
  );
}

動作画面

続き

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?