LoginSignup
5
2

More than 3 years have passed since last update.

React Hook Form 触ってみた

Last updated at Posted at 2021-02-22

React Hook Formとは

Reactと使用できるフォームバリデーションライブラリ。
React Nativeでも使用することが可能。

今回はもくもく会で、React Hook Formを使用したのでその所感と、学べたことを紹介していきます。

今回の紹介コード

Login.tsx
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useForm } from "react-hook-form";

import { fetchAsyncLogin } from '../../../stores/slices/userSlice'
import { hot } from 'react-hot-loader'

import Header from '../../components/block/Header'
import Footer from '../../components/block/Footer'

interface loginFormInput {
  userName: string;
  passWord: string;
}

const Login = () => {
  const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();
  const dispatch = useDispatch()
  const history = useHistory()

  const onSubmit = (data: FormData) => {
    dispatch(fetchAsyncLogin(data))
    reset()
  }


  return (
    <div>
      <Header />
      <h1 css={LoginTitle}>Login Page</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input
          type="text"
          name="userName"
          aria-invalid={errors.userName ? "true" : "false"}
          ref={register({ required: true })}
          placeholder="user"
        />
        {errors.userName && errors.userName.type === "required" && <span role="alert">必須だよ!</span>}
        <input
          type="text"
          name="passWord"
          aria-invalid={errors.passWord ? "true" : "false"}
          ref={register({ required: true, pattern: /^[A-Za-z]+$/i })}
          placeholder="pass"
        ></input>
        {errors.passWord && errors.passWord.type === "required" && <span role="alert">必須だよ!</span>}
        {errors.passWord && errors.passWord.type === "pattern" && <span role="alert">半角英数字でお願いします!</span>}
        <input type="submit" />
      </form>
      <Footer />
    </div>
  )
}

export default hot(module)(Login)

インストール

まず使用するにはインストールが必要

$ npm install react-hook-form

ライブラリをインポート

バリデーションチェックを行うファイルにて、react-hook-formをインポート

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

registerについて

紹介ファイルにて、以下のような記述がある。

const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();

ここでuseFormから取り出しているregisterは、バリデーションをチェックするinputをフックに登録するためのものである。

<input
  type="text"
  name="userName"
  aria-invalid={errors.userName ? "true" : "false"}
  ref={register({ required: true })}
  placeholder="user"
/>

上記のコードのようにrefに対して、registerを設定するとinputのvalueをチェックし、取得できるようになる。

バリデーションの種類

<input
  type="text"
  name="userName"
  aria-invalid={errors.userName ? "true" : "false"}
  ref={register({ required: true })}
  placeholder="user"
/>

先ほどregisterの紹介を行いました。コードをみるとregister内にrequired: trueと設定されている。
register内でこのような設定を行うと、どのようなバリデーションチェックを行うかを設定できるようになっている。
今回のコードの場合は必須かチェックを行うようになっている。
register内で設定できるバリデーションの種類は以下のようになっている。

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate

エラー表示について

エラー表示する際にはerrorsオブジェクトを定義しないといけません

const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();

上記のようにerrorsを定義することで準備完了です。

<input
  type="text"
  name="userName"
  aria-invalid={errors.userName ? "true" : "false"}
  ref={register({ required: true })}
  placeholder="user"
/>
{errors.userName && errors.userName.type === "required" && <span role="alert">必須だよ!</span>}

上記コードのようにerrors.{name属性名}でエラーを確認することができる。

useFormの初期設定について

userForm()とされているが実は()内は省略されている記述が存在する。

それはuseFormの設定である。

const { register } = useForm({
  mode: 'onSubmit',
  reValidateMode: 'onChange',
  defaultValues: {},
  resolver: undefined,
  context: undefined,
  criteriaMode: "firstError",
  shouldFocusError: true,
  shouldUnregister: true,
})

デフォルトではこのように設定されている。

なので初期バリデーションはmodeで設定されているonSubmitを元に行われている。
ということはこのonSubmitを変更すれば他のイベントリスナーでバリデーションを行える。

設定できるmode(イベントリスナー)の種類

  • onSubmit(Default)
  • onBlur
  • onChange
  • onTouched
  • all

アクセシビリティについて

以下のコードのように、aria-invalid属性を記述しさらにrole="alert"を記述することでどのname属性がどのようなエラーメッセージかをスクリーンリーダーで確認できるようになる。

 <input
   type="text"
   name="userName"
   aria-invalid={errors.userName ? "true" : "false"}
   ref={register({ required: true })}
   placeholder="user"
 />
{errors.userName && errors.userName.type === "required" && <span role="alert">必須だよ!</span>}

おわり

一旦ざっとアウトプットしてみましたがまだまだ理解不足な箇所があるので、随時更新もしくは新しく記事を書いていきたいと思います。

参照記事

React Hook Form

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