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

Posted at

実務で、React Hook FormとYupを使ったバリデーション付きフォームを実装したので、
備忘録として残したいと思います。

まず、React Hook FormとはReactでフォームを簡単に扱うことができるライブラリです。
(詳細は割愛いたします:bow:

本記事では、React Hook FormとYupを組み合わせて、シンプルなバリデーション付きフォームを作成する方法を記載します。


全体の流れ

  1. Yupでバリデーションルールを定義
    yupを使ってフォームの入力値に対するバリデーションを定義

  2. React Hook Formでフォームを管理
    useFormフックを使って、フォームの状態やバリデーションエラーを管理

  3. YupのスキーマをReact Hook Formに適用
    yupResolverを使って、React Hook FormにYupスキーマを紐付け

  4. 入力項目にregisterを割り当てる
    React Hook Formのregister関数を使って、フォームの各フィールドを紐付け

  5. handleSubmitでフォーム送信処理
    バリデーションを通過した場合にのみ送信処理を実行


1. Yupでバリデーションルールを定義する

まず、Yupを使ってフォームのバリデーションルールを定義します。

ここでは簡単に名前とメールアドレスを入力するだけのフォームとします。

import * as yup from "yup";

const formSchema = yup
  .object({
    name: yup.string().required("名前を入力してください"),
    email: yup
      .string()
      .email("有効なメールアドレスを入力してください")
      .required("メールアドレスを入力してください"),
  })
  .required();

export type FormValues = yup.InferType<typeof formSchema>;

このスキーマでは以下をチェックします

  • name: 空欄ではないこと
  • email: 有効なメールアドレス形式であること、および空欄ではないこと

yup.InferTypeについて

  • Yupで定義されたバリデーションスキーマ(formSchema)を元にして、TypeScriptの型定義(FormValues)を生成
  • Yupスキーマで定義したフィールド名やデータ型が、TypeScriptの型定義に自動的に反映されるため、スキーマと型定義の間で不整合が起きるリスクを防ぐことができる

2. React Hook Formでフォームを管理する

次に、useFormを使ってフォームの状態管理とバリデーションを設定します。


import React from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";

const formSchema = yup
  .object({
    name: yup.string().required("名前を入力してください"),
    email: yup
      .string()
      .email("有効なメールアドレスを入力してください")
      .required("メールアドレスを入力してください"),
  })
  .required();

export type FormValues = yup.InferType<typeof formSchema>;

const MyForm = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: yupResolver(formSchema), // Yupのスキーマを紐付ける
    defaultValues: { name: "", email: "" }, // 初期値の設定
  });

  const onSubmit = (data: FormValues) => {
    console.log("フォームデータ:", data);
    // dataには、registerで紐付けたフォームフィールド(nameとemail)の入力値が格納される。
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>名前:</label>
        <input {...register("name")} />
        {errors.name && <p>{errors.name.message}</p>} {/* バリデーションエラーの表示 */}
      </div>

      <div>
        <label>メールアドレス:</label>
        <input {...register("email")} />
        {errors.email && <p>{errors.email.message}</p>} {/* バリデーションエラーの表示 */}
      </div>

      <button type="submit">送信</button>
    </form>
  );
};

export default MyForm;

フォーム

image.png

ポイント解説

1. useFormとは?

useFormは、React Hook Formが提供するフォーム管理のメインフックです。フォーム全体を管理するための設定や関数、状態を取得できます。

使い方

以下のようにuseFormを呼び出すことで、フォームの管理に必要な機能をまとめて取得できます。

const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm<FormValues>({
  resolver: yupResolver(formSchema),
  defaultValues: { name: "", email: "" },
});

主な設定オプション

  • resolver:
    バリデーションを外部ライブラリ(Yupなど)に委託するための設定。ここでは、yupResolverを使い、Yupスキーマに基づいたバリデーションを行っている

  • defaultValues:
    各フィールドの初期値を設定。この例ではnameemailの初期値を空文字列("")にしている

2.registerとは

registerは、各フォームフィールドをReact Hook Formに登録するための関数です。これを使って、フォームの入力値や状態をReact Hook Formで管理できるようにします。

使い方

以下のように、フォーム要素にregisterを適用します:


<input {...register("name")} />
<input {...register("email")} />

ここで渡す引数(例:"name")は、フォームデータ内のフィールド名を指定します。これにより、React Hook Formがそのフィールドを認識し、管理対象とします。

機能

  • 入力値の監視と取得:ユーザーが入力した値をリアルタイムで管理
  • バリデーションの紐付け:resolverで設定したスキーマに基づいて入力値を検証する

3. handleSubmitとは?

handleSubmitは、フォームの送信時にバリデーションを実行し、成功時に指定した関数(onSubmit)を呼び出すための関数です。

使い方

フォームのonSubmitイベントに以下のように設定します:

<form onSubmit={handleSubmit(onSubmit)}>

動作の流れ

  1. フォームが送信される:ボタンを押すことで、onSubmitイベントが発火
  2. バリデーションの実行resolverで指定したYupスキーマに基づいて入力値が検証される
  3. 成功時(バリデーション通過時)
    • onSubmit関数が実行され、検証済みの入力データ(data)が引数として渡される
  4. 失敗時(バリデーションエラー発生時)
    • エラー情報がformState.errorsに格納される
 const onSubmit = (data: FormValues) => {
    console.log("フォームデータ:", data);
    // registerで紐付けたフォームフィールド(nameとemail)の入力値が格納される。
    // 実際にはAPIの処理などが入る。
  };

4. formState.errorsとは?

formState.errorsは、バリデーションエラーの状態を管理するオブジェクトです。

各フィールドごとにエラー情報を格納し、ユーザーにエラー内容を表示する際に利用します。

使い方

{errors.name && <p>{errors.name.message}</p>}
  • errors.name: nameフィールドに対するエラー情報を持っている
  • errors.name.message: エラーメッセージ(Yupスキーマで指定した文言)が格納されている

image.png

コード全体の流れ

  1. フォームの管理をuseFormでセットアップ
    • useFormでフォームの初期値やバリデーションを設定
    • 各フィールドをregisterで登録
  2. フォーム送信時にhandleSubmitでバリデーション実行
    • バリデーションを通過した場合、onSubmit関数が呼び出される
    • エラーがある場合は、formState.errorsにエラー情報が格納される
  3. エラーがあればユーザーに表示
    • 各フィールドごとにerrorsをチェックし、エラーメッセージを表示

※完成したフォーム

image.png

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?