2
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?

More than 3 years have passed since last update.

React-Hook-Formの使い方(Part1:RHFだけでバリデーション)🌟

Last updated at Posted at 2021-10-31

はじめに

初見時に公式を読んで「どういうこと?」となったためまとめます。公式読んでスッキリしていない方はこちらを読んでからならスムーズに読めるかもしれません。
また、この記事はpartに分けています。part1ではRHFだけのバリデーション。part2ではyupとの併用。part3ではMUIのバリデーションを行います。

パッケージインストール

npm install react-hook-form
yarn add react-hook-form

RHF基本的な使い方

詳細な使い方を説明する前にinput要素の値の取得からバリデーションという一連の流れを説明します。

まずはじめにinput要素にRHFのregisterという関数を適用することで、input要素をRHFから参照できるようにします。次に適用するバリデーションをregister関数に登録します。最後にsubmitボタンを作成しonSubmitで発火する関数をRHFから取得します。

では次の項目から上記で説明した内容とエラーメッセージの出し方の詳細な方法を説明します。

目次

  • フィールドの登録
  • バリデーション適用
  • Submitする
  • エラーメッセージの出し方

フィールドの登録

以下React-Hook-Form(RHF)公式のクイックスタートより引用

React Hook Form の重要なコンセプトの一つは、非制御コンポーネント ([Uncontrolled Components]を
フックに登録(register) し、フォームフィールドの値を検証と収集できるようにすることです。
URL: https://react-hook-form.com/jp/get-started#Quickstart

これだけではよくわからないので補足します。
RHFは使えばinput要素の値(value属性)をuseStateで監視する必要はありません。RHFは非制御コンポーネントの入力を監視してバリデーションすることができます。
バリデーションするにはRHFが提供するカスタムフックである、registerを使って非制御コンポーネントを登録する必要があります。registerはカスタムフックなので以下の方法で取得できます。

const { register } = useForm();

そして実際の非制御コンポーネントの登録は以下のように行います。

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

これで上記のinput要素は"email"というname属性で登録されました。
これで、フォームフィールドのバリデーションと収集ができるようになりました。
※name属性は必ず一意になるようにする必要があります。

バリデーション

registerによる登録はできたので、次はバリデーションを適用します。
yupなどのバリデーションライブラリを利用する方法がありますが、今回はRHFで用意されているものを使ってバリデーションしていきます。
やり方は簡単でregisterの第2引数にバリデーションを定義したオブジェクトを渡すだけです。

<input {...register("email",  { required: true, maxLength: 20 } )} />   

上記は「必須入力」・「最大文字数20文字」というバリデーションを行っています。
他にもあるので公式を見て自分が実装したバリデーションを探してみてください。
https://react-hook-form.com/api/useform/register

Submitする

次にSubmitしたいと思います。コードは以下の様になっているとします。

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

// コンポーネント
export const App = () => {
  // カスタムフック
  const { register } = useForm();

  // jsx
  return (
    <input {...register("email",  { required: true, maxLength: 20 } )} />         
  );
};

まずは、formのHTML要素とsubmitするためのボタンを追加します。

    <form>
      <input {...register("email",  { required: true, maxLength: 20 } )} />   
      <input type="submit" />
    </form>

これで、submitする準備はできました。あとはonSubmitをform要素に持たせればよいです。
ここでuseFormからhandleSubmit関数を取得してonSubmitのイベントリスナーに登録します。

const { register, handleSubmit } = useForm();

<form onSubmit={handleSubmit()}>
    <input {...register("email",  { required: true, maxLength: 20 } )} /> 
    <input type="submit" />
</form>

handleSubmitの引数には関数(formSubmitHandler)を渡します。formSubmitHandlerはinputの値をオブジェクトで受け取ることが出来ます。
またformSubmitHandlerの定義と同時に「formSubmitHandler」と「inputの値」の型定義をしてあげましょう。

  1. formSubmitHandlerの型定義はrect-hook-formからimportできます。
  2. inputの値はオブジェクトで渡ってくるのでオブジェクトで定義します。
  3. useFormにもinputの値の型定義を渡します。
// 渡す関数の型定義はimportする
import { useForm, SubmitHandler } from "react-hook-form";
// inputの値の型定義
type IFormInputs = {
  email: String;
};
// SubmitHandlerにはinputの値の型定義を渡します。
const formSubmitHandler: SubmitHandler<IFormInputs> = (data) => {
  console.log(data);
};

// コンポーネント
export const App = () => {
  // useFormにも型定義をします
  const { register, handleSubmit } = useForm<IFormInputs>();

  // jsx
  return (
    <form onSubmit={handleSubmit(formSubmitHandler)}>
      <input {...register("email",  { required: true, maxLength: 20 } )} /> 
      <input type="submit" />
    </form>
  );
};

コメントなしのコード

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

type IFormInputs = {
  email: String;
};

const formSubmitHandler: SubmitHandler<IFormInputs> = (data) => {
  console.log(data);
};

export const App = () => {
  const { register, handleSubmit } = useForm<IFormInputs>();

  return (
    <form onSubmit={handleSubmit(formSubmitHandler)}>
      <input {...register("email",  { required: true, maxLength: 20 } )} /> 
      <input type="submit" />
    </form>
  );
};

これで完成です。20文字以下の入力があればsubmitした瞬間にformSubmitHandlerが動いて
console.logに以下の様な内容が出力されるはずです。

{email: "入力値"}

エラーメッセージの出し方

エラーメッセージを出すのは簡単です。
useFormからerrorオブジェクトを取得し、そのエラーオブジェクトの中身がある場合はエラーメッセージを出すようにします。
エラーオブジェクはregisterで登録したname属性のプロパティを持ちます。submitの時にバリデーションをパスできなければerrorオブジェクトの中身が生成されます。

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

type IFormInputs = {
  email: String;
};

const formSubmitHandler: SubmitHandler<IFormInputs> = (data) => {
  console.log(data);
};

export const App = () => {
  const {
    register,
    handleSubmit,
    formState: { errors } // errorオブジェクト
  } = useForm<IFormInputs>();

  return (
    <form onSubmit={handleSubmit(formSubmitHandler)}>
      <input {...register("email", { required: true, maxLength: 20 })} />
      <input type="submit" />
      <br />
      // errorオブジェクトのemailが値を持つとき
      {errors.email && <span style={{ color: "red" }}>エラー</span>}
    </form>
  );
};

最後に

以上でRFHだけを使ったバリデーションの説明は終わりです。より詳細なバリデーション方法を知りたい場合は公式を読むと良いでしょう。また、ここで紹介しなかったwatchなどのuseFormが持つAPIを確認することも重要なことかもしれません。(watchは使い道がわからなかったので、紹介できませんでした。)

part2ではyupを使ったバリデーションを説明します。part3ではMUIをバリデーションしたいと思います。

以上です。記事を読んでくださりありがとうございました。

2
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
2
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?