React useFormを利用してformを作成する
React Hook Form
Reactでフォームを作るとき、フォームごとuseStateで入力値を管理したり、フォームのバリデーションを直接書いたりしてかなり大変です。
その時利用できるのがReact Hook FormのuseForm
です。
今回は以下のサンプルで使った部分だけ絞って説明したいと思います。サンプルのデザインにはtailwind CSSを利用しています
ソースコード
公式ドキュメント
インストール
$ npm install react-hook-form
// react18利用中にDependancyエラーの場合
// react18の場合まだ使えないため、後ろに --legacy-peer-deps をつけてインストールします
$ npm install react-hook-form --legacy-peer-deps
インストールできたらimportして利用できます。
import { useForm } from "react-hook-form";
useFormについて
// formで利用する値のtype指定
interface LoginForm {
email: string;
password: string;
}
// 利用するメソッドを定義しています。ここの今回メソッドを以下で説明します。
const {
register,
watch,
handleSubmit,
formState: { errors },
} = useForm<LoginForm>();
method
register
フォームから入力された値のstate管理、バリデーション処理が可能です。
以下のソースコードではemailフォームの値を受け取り、項目入力必須のバリデーション処理を書いています。
<div className="flex w-full flex-col">
<label className="text-sm text-gray-800" htmlFor="email">
Email
</label>
<input
{...register("email", { required: "emailを入力してください" })}
className="rounded-md border px-3 py-2 focus:border-2 focus:border-teal-500 focus:outline-none"
type="email"
name="email"
/>
</div>
watch
フォームの値変更の監視ができます。ドキュメントにはチェックボックスにチェックをつけるとフォームを表示させる例が乗っていました。
handleSubmit
フォームをsubmitした時の処理をかけます。handleSubmit()
は引数を二つ受け取ります。
引数1はバリデーション処理がOKの場合の関数、引数2はバリデーション処理がNGの場合に呼ばれる関数が入ります。
以下のソースコードだとpasswordがバリデーション失敗した時に、このようにconsole.logされます。
// バリデーション処理がOKの場合に呼ばれる関数
const isValid = (data: LoginForm) => {
console.log(data);
};
// バリデーション処理がNGの場合に呼ばれる関数
const isInValid = (erros: any) => {
console.log(errors);
console.log("Fail Login");
};
<form onSubmit={handleSubmit(isValid, isInValid)} className="flex w-full flex-col items-center space-y-5 ">
//省略
</form>
formState
フォームの状態をobjectで管理しています。
formState: { errors, isDirty, isSubmitting, touchedFields, submitCount }
いろんな状態を使えますがここでは一番利用するerrors
だけ説明します。
フォームでエラーになった場合、errors.[項目名]
にエラーのobjectが入ります。{errors.password?.message}
のように書くと画面上でフォームのエラーメッセージを表示できます。
<input
{...register("password", {
required: "passwordを入力してください",
minLength: { value: 8, message: "8文字以上入力してください" },
})}
className="rounded-md border px-3 py-2 focus:border-2 focus:border-teal-500 focus:outline-none"
type="password"
name="password"
/>
<div className="mt-1 font-semibold text-rose-500">
{errors.password?.message}
</div>
Props
今回はデフォルトのonSubmitだったため、ソースコード上にはありません。
useForm自体にも様々なpropsを受け取ってカスタマイズできます。
useForm({
mode: 'onSubmit',
reValidateMode: 'onChange',
defaultValues: {},
resolver: undefined,
context: undefined,
criteriaMode: "firstError",
shouldFocusError: true,
shouldUnregister: false,
shouldUseNativeValidation: false,
delayError: undefined
})
その中で mode
ですが、バリデーションチェックをするタイミングの指定ができます。
onSubmit
デフォルトはonSubmitです。submitした時にエラーが表示されます。
onChange
入力時に検知してエラーが表示されます。
onBlur
inputの外をクリックした時にエラーが表示されます。onBlubのサンプルです。
const {
register,
watch,
handleSubmit,
formState: { errors },
} = useForm<LoginForm>();
まとめ
useFormを利用すると、かなり簡単にフォームを完成することができます。
またドキュメントにもバリデーションサンプルなど親切に書いてあるので、使う時にはぜひ読んでみてください。
Discussion