ZU TECH BLOG

MUIのTextFieldとReact Hook Formでバリデーションを実装する

はじめに

こんにちは、 @zsp2088dev です。
最近、MUIのTextFieldとReact Hook Formを使用してバリデーションを実装しました。
実装方法を調べてみるといくつか方法があり、戸惑ってしまいました。
本記事では、MUIのTextFieldとReact Hook Formを使用したバリデーションの実装方法について紹介します。

フォームの用意

MUIのTextFieldとButtonを縦に並べたものをサンプルとして用意しました。

2022-05-11-form.png

フォームの入力内容に誤りがある場合は、エラーメッセージを表示が表示されることを期待します。
今回は、ユーザー名とメールアドレスを必須項目としてサンプルを作成しました。

React Hook Formのドキュメント必須項目以外のルールについて記述があるので、詳細はこちらを参考にしてください。

2022-05-11-form-error.png

バリデーションの実装方法

以下に記載するのは共通で使用する箇所のコードです。
ユーザー名とメールアドレスを記入するフォームを想定しています。

type SampleForm = {
  name: string;
  email: string;
}

const SampleFormPage = () => {
  const {
    control,
    handleSubmit,
    register,
    formState: { errors },
  } = useForm<SampleForm>({
    defaultValues: {
      name: "",
      email: "",
    },
  });
}
 
 return (...)
}

1. formStateで実装

まずは、チュートリアルでも説明されているformStateによるバリデーションの実装方法です。
フォームに入力した値を扱うためのregisterは、RegisterOptionsを引数に受け取ることができます。
このRegisterOptionsにはルールとそれに違反したときのメッセージを指定することで、エラー時に指定したエラーメッセージを表示することができるようになります。
このとき、errorにはエラー条件を、helpetTextにはエラーメッセージを指定します。
formStateのerrorsからフォーム入力のエラーを受け取ることができるため、errorとhelperTextには、errorsの値を使用しています。

<TextField
  label="ユーザー名"
  type="text"
  {...register("name", { required: "ユーザー名の入力は必須です" })}
  error={!!errors.name}
  helperText={errors.name?.message}
/>

2. Controller + formStateで実装

ControllerとformStateを使用してバリデーションを行います。
Controllerのrulesにバリデーションのルールを指定し、renderにTextFieldを指定します。
errorとhelperTextについては1と同じです。

<Controller
  name="name"
  control={control}
  rules={{ required: "ユーザー名の入力は必須です" }}
  render={({ field }) => (
    <TextField
      {...field}
      label="ユーザー名"
      type="text"
      {...register("name")}
      error={!!errors.name}
      helperText={errors.name?.message}
    />
  )}
/>

3. Controller + fieldStateで実装

2と同様にControllerを使用します。
ここでは、fieldStateのerrorを使用してエラー条件とエラーメッセージの表示を行います。

<Controller
  name="name"
  control={control}
  rules={{ required: "ユーザー名の入力は必須です" }}
  render={({ field, fieldState: { error } }) => (
    <TextField
      {...field}
      label="ユーザー名"
      type="text"
      {...register("name")}
      error={!!error}
      helperText={error?.message}
    />
  )}
/>

また、fieldState.invalidについては、非推奨となっているため、fieldState.errorに置き換えたほうがよさそうです。

4. Textfieldのみの簡易バリデーション

Textfieldそのものにrequiredを指定することで、簡易的なバリデーションを行うことができます。
ただし、この方法ではエラーメッセージを指定することができないことや、凝ったエラー条件を指定することができないことに注意しなくてはなりません。

<TextField
  required
  label="ユーザー名"
  type="text"
  {...register("name")}
/>

また上記3つと比較をすると、エラーメッセージの見た目も異なります。
2022-05-11-textfield-required.png

おわりに

本記事では、MUIのTextFieldとReact Hook Formを使用したバリデーションの実装方法について紹介しました。
色々な書き方があったため、どれがいいのかなと悩むところです。
また、Yupのような外部のパッケージを使用してバリデーションを行うこともできるので、ますます悩んでしまいます。
最後まで読んでいただき、ありがとうございました!

参考

© 2022 zsp2088dev