Next.js(React)でログイン機能を実装していて、フォーム作成に苦戦していました。 そもそも、Reactを全然理解していないので、フォームの値はどうやって取得すればいいのか?みたいなところからわかりませんでした。
今回はReact+TypeScriptでフォームを作成するのにReact Hook Formがとても便利だったので、紹介します。
React Hook Formとは
公式サイトを見ると「高性能で柔軟かつ拡張可能な使いやすいフォームバリデーションライブラリ」らしいです。
詳細は以下公式サイトを見てください。
React Hook Form
さっそく実装をする
まずはReact Hook Formをインストールします。 以下コマンドをプロジェクト配下で実行します。
npm install react-hook-form
インストールしたら、import
してフォームの値をサポートするためのFormData
型を作成します。
import { useForm } from "react-hook-form";
type FormData = {
username: string;
password: string;
};
今回はログイン用のフォームを作成するために、string
型のusername
とpassword
を用意しました。
次に、useForm
を使ってフォーム作成に必要なメソッドを受け取ります。
import { useForm } from "react-hook-form";
type FormData = {
username: string;
password: string;
};
export default function Login() {
const { register, handleSubmit, watch, errors } = useForm<FormData>();
}
useForm<FormData>()
のように書いてフォームで使う型を設定できます。
const
で定義されているメソッドについては以下にまとめました。
register
: input/selectのRefとバリデーションルールをReact Hook Formに登録するhandleSubmit
: フォームバリデーションに成功するとフォームデータを渡すwatch
: 指定されたinput/inputsを監視し、その値を返すerrors
: 各inputのフォームのエラーまたはエラーメッセージを含む
これらのメソッドを使って、フォームを作成します。
import { useForm } from "react-hook-form";
type FormData = {
username: string;
password: string;
};
export default function Login() {
const { register, handleSubmit, watch, errors } = useForm<FormData>();
const onSubmit = (data: FormData): void => console.log(data);
console.log(watch("username"));
console.log(watch("password"));
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="filed">
<label className="label">username</label>
<input
name="username"
placeholder="username"
ref={register({ required: true })}
/>
{errors.username && "usernameを入力してください。"}
</div>
<div className="filed">
<label className="label">password</label>
<input
name="password"
placeholder="password"
ref={register({ required: true })}
/>
{errors.password && "passwordを入力してください。"}
</div>
<div className="filed">
<button>login</button>
</div>
</form>
);
}
フォームの流れにそって解説します。
フォームのinput
で作成したFormData
を使うためにはname
属性に設定します。また、ref={register({ required: true })}
のように書くことで、input
は入力必須にしています。
{errors.username && "usernameを入力してください。"}
はusername
がバリデーションエラーになったら表示されます。最後に、フォームに入力をしてボタンを押してバリデーションエラーが発生していない場合、<form onSubmit={handleSubmit(onSubmit)}>
が動いて、const onSubmit = (data: FormData): void => console.log(data);
が実行されてコンソールに入力された値が表示されます。
フォームに入力がない状態でボタンを押すと以下のような挙動をします。
console.log(watch("username"));
はusername
に入力された値が変わるとその都度コンソールに表示します。
まとめ
普通にReactでフォームを作成するとコードが長くなりやすいですが、React Hook Formを使うことでとても簡単にフォーム作成ができました。便利なのでぜひ使ってみてください。
(マークダウンでTypeScriptのコードを書いたときに</>が赤く塗られているのなんか気持ち悪いな。)