技術系

React-hook-formでフォームを作るヨ

技術系

こんにちは、なかにしです。

フロントエンジニアをしていたら、フォーム系の作成はほぼ必須ですよね。

最近はReact-hook-formをよく使用するので、基礎的な部分をまとめます。

react-hook-formとは

Reactのライブラリです。
簡単にフォーム作成と、フォームの入力値の操作が出来ます。

Reactのプロジェクトを作成して、react-hook-formをインストールします。

npm install react-hook-form

フォーム作成

フォームを作成していきます。

reach-hook-form内に内包している「useForm」を使用して設定をしていくのですが、
いきなり書いても分かりづらいので、まずは普通にReact単体でフォームを書きます。

import { useState } from 'react';
import './App.css';

function Form() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = (e: any) => {
    e.preventDefault();
    console.log({
      email,
      password,
    });
  };

  const handleChangeEmail = (e: any) => {
    setEmail(e.target.value);
  };
  const handleChangePassword = (e: any) => {
    setPassword(e.target.value);
  };

  return (
    <div className="App">
      <h1>ログイン</h1>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="email">Email</label>
          <input
            id="email"
            name="email"
            value={email}
            onChange={handleChangeEmail}
          />
        </div>
        <div>
          <label htmlFor="password">パスワード</label>
          <input
            id="password"
            name="password"
            value={password}
            onChange={handleChangePassword}
            type="password"
          />
        </div>
        <div>
          <button type="submit">ログイン</button>
        </div>
      </form>
    </div>
  );
}

export default Form;

useStateを使用して、emailとpasswordを保持し、
onSubmitで中身を表示しています。

ここから、react-hook-formに置き換えていきます。

register()

まず、inputの部分です。

inputは、register()で代用します。

// react-hook-formなし
<input
 id="email"
  name="email"
  value={email}
  onChange={handleChangeEmail}
 />

// react-hook-formあり
<input 
 id="email"
 {...register("email")}
/>

上記のように、nameやonChangeの部分を、
register関数で一気に置き換えることが出来ます。

handleSubmit()

次に、入力値の取り出しです。
useStateの方は、handleSubmit関数を定義し、どんな挙動をするのかを記述しました。

react-hook-formを使用すると、以下のようになります。

function Form() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const { register, handleSubmit } = useForm();

  const nice = (e: any) => {
    console.log(e)
  }

  return (
    <div className="App">
      <h1>ログイン</h1>
      <form onSubmit={handleSubmit(nice)}>
        <div>
          <label htmlFor="email">Email</label>
          <input id='email' {...register('email')} type='email' />
        </div>
        <div>
          <label htmlFor="password">パスワード</label>
          <input id='password' {...register('password')} type='password' />
        </div>
        <div>
          <button type="submit">ログイン</button>
        </div>
      </form>
    </div>
  );
}

export default Form;

handleSubmit関数が、予め定義されています。
handleSubmitをuseFormからインポートして、それを使用します。

handleSumbit関数は引数として関数を取りますので、
その関数(今回はnice関数)を定義して、どんな挙動にするかを記述してあげます。

今回は、中身を出力するだけにしました。
入力項目を埋めて、ログインボタンを押すと、以下のような値が返ってきます。

特にオブジェクトの設定をしていないのに、
{inputのname: 入力値}という結果を返してくれます。

これは非常に便利ですね。

バリデーション

先ほどまでの置き換えの結果として、以下になっています。

import { useForm } from 'react-hook-form';
import './App.css';

function NewForm() {
  const { register, handleSubmit } = useForm();

  const nice = (e: any) => {
    console.log(e)
  }

  return (
    <div className="App">
      <h1>ログイン</h1>
      <form onSubmit={handleSubmit(nice)}>
        <div>
          <label htmlFor="email">Email</label>
          <input id='email' {...register('email')} type='email' />
        </div>
        <div>
          <label htmlFor="password">パスワード</label>
          <input id='password' {...register('password')} type='password' />
        </div>
        <div>
          <button type="submit">ログイン</button>
        </div>
      </form>
    </div>
  );
}

export default NewForm;

これだけでformとしては充分な役割を果たしてくれますが、
react-hook-formの強みは、これだけではありません。

なんと、バリデーションも簡単に導入できます。

例えば、required。

<input id='password' {...register('password', {required: true})} type='password' />

registerと同時に{required: true}と定義すると、必須の役割を持ちます。

いやいや、そんなん以下で良いでしょ。と思うかも知れませんが、

  <input id='password' {...register('password')} type='password' required />

register()内で設定したバリデーション項目は、
独自のエラーメッセージを出力出来ます。

// errorsをインポート
const { register, handleSubmit, formState: { errors } } = useForm();

...省略...

  <input id='email' {...register('email', { required: true })} type='email' />
  {errors.email && <div>emailを入力して!!!!!!</div>}

これで、emailの項目が空だった場合のみ、「emailを入力して!」が出ます。

以下はrequiredとminLengthを同時に設定した場合です。

入力値が空であれば、「emailを入力せよ」が表示されますし、
入力値が8文字未満であれば、「8文字以上で入力して」が表示されます。

<input
  id='email'
  {...register('email', {
    required: {
    value: true,
    message: "emailを入力せよ"
  },
  minLength: {
    value: 8,
    message: "8文字以上で入力して"
  }
  })} 
  type='email' />
{errors.email?.message && <div>{errors.email.message}</div>}

送信ボタン

「isValid」でバリデーションが通っているかを確認出来ます。
設定したバリデーションが全て通っていればisValidはtrueになります。

これを使用して、送信ボタンの on/off を切り替えます。

const { register, handleSubmit, formState: { errors, isValid } } = useForm();

...省略...

<button type="submit" disabled={!isValid}>ログイン</button>

わざわざuseStateで管理する必要がないのは便利ですね。

さいごに

今回はReact-hook-formの基本的な使い方の部分をおさらいしました。

やっぱりコードが短く整理されると、気持ちが良いですね。

今回はここまで!
Enjoy Hacking!!

タイトルとURLをコピーしました