ReactでReact Hook Formを使う

Reactでフォームを作成するときにはReact Hook Formを使うことで簡単に実装することができます。Reactのみで実装する場合はフォームごとにuseStateを用意する必要がありましたがそういった手間も省くことができます。

また簡単にというのはコード量が少なくなるだけではなく、バリデーションも簡単に実装することができます。バリデーションについては他ライブラリと合わせて使うこともでき柔軟性もあります。

今回はこのReact Hook Formを使ったシンプルな構成の場合について順番にみていきたいと思います。

最小構成の場合

input要素またはsubmit要素を登録するregisterメソッドとフォームデータを受け取るhandleSubmitメソッドを利用することによって以下のようにシンプルな記述でフォームを実装することができます。

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

interface Props {
  firstName: string;
  lastName: string;
}

export default function Form() {
  const { register, handleSubmit } = useForm<Props>();
  const onSubmit: SubmitHandler<Props> = ({ firstName, lastName }) =>
    alert(`firstName: ${firstName} lastName: ${lastName}`);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First Name</label>
      <input {...register("firstName")} />
      <label>Last Name</label>
      <input {...register("lastName")} />
      <input type="submit" value="submit" />
    </form>
  );
}

バリデーションを含めた場合

バリデーションを含めるとこのようになります。(この段階ではエラーハンドリングは含めていません。)

registerに対してバリデーションのルールを渡します。

定義することのできるルールは以下となります。

  • required (boolean): 入力必須か
  • min (number): 最小入力値(整数)
  • max(number): 最大入力値(整数)
  • minLength(number): 最小入力文字数
  • maxLength(number): 最大入力文字数
  • pattern(RegExp): 正規表現で検証
  • validate(Function | Object): コールバック関数で独自に検証ルールを定義
import { useForm, SubmitHandler } from "react-hook-form";

interface Props {
  firstName: string;
  lastName: string;
}

export default function Form() {
  const { register, handleSubmit } = useForm<Props>();
  const onSubmit: SubmitHandler<Props> = ({ firstName, lastName }) =>
    alert(`firstName: ${firstName} lastName: ${lastName}`);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First Name</label>
      <input {...register("firstName", { required: true, maxLength: 20 })} />
      <label>Last Name</label>
      <input {...register("lastName", { required: true, maxLength: 20 })} />
      <input type="submit" value="submit" />
    </form>
  );
}

エラーハンドリングを含めた場合

useFormでformState: { errors }を宣言しバリデーションでエラーがあった際に検知できるようにします。

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

interface Props {
  firstName: string;
  lastName: string;
}

export default function Form() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<Props>();
  const onSubmit: SubmitHandler<Props> = ({ firstName, lastName }) =>
    alert(`firstName: ${firstName} lastName: ${lastName}`);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First Name</label>
      <input {...register("firstName", { required: true })} />
      {errors.firstName && <p>First name is required</p>}
      <label>Last Name</label>
      <input {...register("lastName", { required: true })} />
      {errors.lastName && <p>Last name is required</p>}
      <input type="submit" value="submit" />
    </form>
  );
}

まとめ

シンプルにフォームを作成することができました。

React-Hooks-Formは非常に便利ですので積極的に利用していきたいですね。