🐒

【React】入力のバリデーションはreact-hook-formで決まり!

2022/05/27に公開
1

こんにちは@nerusanです。

皆さんは、入力フォームの検証は何を利用しておりますでしょうか。
デフォルトでは、htmlの検証を利用している方もいるのではないでしょうか。
たとえば、以下のように記述できます。

const onSubmit = (event) => {
  event.preventDefault();
  // 送信ボタン押した後の処理
}
  
export const Components = () => {
  return (
    <form onSubmit={onSubmit}>
      <h1>ユーザ名</h1>
      <input minLength={7} required />
    </from>
  );
}

結果

このやり方でもいいのですが、フォーム実行時event.preventDefault()を入れる必要があったり、デフォルトでの検証表示がいまいちだったりし、変更するのも面倒です。

また、入力値を監視、レンダリングのパフォーマンス、初期値リセット時などを考慮すると、stateを用意したり 、メモ化したりと結構めんどくさかったりします。

そこで、入力の検証を便利に使えるhooksであるreact-hook-formを紹介します。

react-hook-formのメリット

以下が挙げられれます。

  • ライブラリも軽量で、レンダリングにおけるパフォーマンスも闔閭してくれる
  • 書き方がシンプルでわかりやすくDXが良い

1つ目は、たとえば、2つの入力フォームを用意するとします(ユーザ名とメアドなど)。何も処理しないと、一方の入力要素に文字を入力するたびに、もう一方の入力要素は何も変更していないけど、再レンダリングされます。これは明らかに無駄なレンダリングであり、パフォーマンス的には良くないです。別途これを考慮するために、メモ化をしないといけません。しかし、react-hook-formは、デフォルトでそれぞれの入力フォームを分離して、レンダリングが互いに影響しないようになっています。なので、パフォーマンス的にはGoodです。

2つ目は、DXということで、開発者にはわかりやすいインターフェースになっており、直感的に利用することもできます。ある程度使うと、ドキュメントを見なくても、使える部分があります。では、実際に使ってみてみましょう!

使ってみよう

今回は、名前('name')とメール('mail')を入力されるフォームを考えます。

sample.tsx
import { useForm } from 'react-hook-form';

// 入力フォームに応じた型
// 今回は名前とメールアドレスを扱う
type Input = { name: string; mail: string };

const Component = () => {
  // 初期化
  const {
    register,
    handleSubmit,
    reset,
    watch,
    formState: { errors },
  } = useForm<Input>();

   // フォーム送信ボタンを押された時の処理
  const onsubmit = (data: Input) => {
    console.log(data);
    reset();   // フォームに入力した値をリセット
  };
  // nameを監視
  // 入力のたびに更新される
  console.log(watch('name');
  
  return (
   <form onSubmit={handleSubmit(onsubmit)}>
      <input {...register('mail', { required: 'メールを入力してね' })} />
      <p>{errors.mail?.message}</p> {/* エラー表示 */}
        <input
        {...register('name', {
          required: '名前を入力してね',
          minLength: { value: 2, message: `2文字以上にしてね` },
        })}
      />
      <p>{errors.name?.message}</p> {/* エラー表示 */}
      <input type="submit" />
    </form>
  )
}

どうでしょうか。

input要素にバリデーションルール及びエラー文言をオブジェクトにより指定できて、直感的ではないでしょうか。

送信ボタンを押した際も、event.preventDefault()も必要がないため、初心者でも躓くことはありません(僕は初め、event.preventDefault`を忘れたことにより、なぜかうまく動作しない!って躓きました。。)。

また、reset()を呼び出すだけで、送信後の入力フォーム欄を初期値に戻すことも簡単です。今回初空白にしていますが、他の値にもできます。

また、watch()関数を利用すことにより、入力の値を常時監視することもできます。useStateを新たに用意する必要もなく、記述量も減ります。便利ですね。

まとめ

今回は、機能のほんの一部のみ紹介しました。
他にも、いつバリデーションをかけるのかなど、バリデーションのための便利な機能がたくさんあります。詳しくは公式ページをご覧ください。

https://react-hook-form.com/jp/

参考

https://qiita.com/NozomuTsuruta/items/60d15d97eeef71993f06

GitHubで編集を提案

Discussion

TakaoTakao
×:console.log(watch('name');
○:console.log(watch('name'));