【React】入力のバリデーションはreact-hook-formで決まり!
こんにちは@nerusanです。
皆さんは、入力フォームの検証は何を利用しておりますでしょうか。
デフォルトでは、htmlの検証を利用している方もいるのではないでしょうか。
たとえば、以下のように記述できます。
const onSubmit = (event) => {
event.preventDefault();
// 送信ボタン押した後の処理
}
export const Components = () => {
return (
<form onSubmit={onSubmit}>
<h1>ユーザ名</h1>
<input minLength={7} required />
</from>
);
}
結果
このやり方でもいいのですが、フォーム実行時event.preventDefault()
を入れる必要があったり、デフォルトでの検証表示がいまいちだったりし、変更するのも面倒です。
また、入力値を監視、レンダリングのパフォーマンス、初期値リセット時などを考慮すると、stateを用意したり 、メモ化したりと結構めんどくさかったりします。
そこで、入力の検証を便利に使えるhooksであるreact-hook-formを紹介します。
react-hook-formのメリット
以下が挙げられれます。
- ライブラリも軽量で、レンダリングにおけるパフォーマンスも闔閭してくれる
- 書き方がシンプルでわかりやすくDXが良い
1つ目は、たとえば、2つの入力フォームを用意するとします(ユーザ名とメアドなど)。何も処理しないと、一方の入力要素に文字を入力するたびに、もう一方の入力要素は何も変更していないけど、再レンダリングされます。これは明らかに無駄なレンダリングであり、パフォーマンス的には良くないです。別途これを考慮するために、メモ化をしないといけません。しかし、react-hook-formは、デフォルトでそれぞれの入力フォームを分離して、レンダリングが互いに影響しないようになっています。なので、パフォーマンス的にはGoodです。
2つ目は、DXということで、開発者にはわかりやすいインターフェースになっており、直感的に利用することもできます。ある程度使うと、ドキュメントを見なくても、使える部分があります。では、実際に使ってみてみましょう!
使ってみよう
今回は、名前('name')とメール('mail')を入力されるフォームを考えます。
import { useForm } from 'react-hook-form';
// 入力フォームに応じた型
// 今回は名前とメールアドレスを扱う
type Input = { name: string; mail: string };
const Component = () => {
// 初期化
const {
register,
handleSubmit,
reset,
watch,
formState: { errors },
} = useForm<Input>();
// フォーム送信ボタンを押された時の処理
const onsubmit = (data: Input) => {
console.log(data);
reset(); // フォームに入力した値をリセット
};
// nameを監視
// 入力のたびに更新される
console.log(watch('name');
return (
<form onSubmit={handleSubmit(onsubmit)}>
<input {...register('mail', { required: 'メールを入力してね' })} />
<p>{errors.mail?.message}</p> {/* エラー表示 */}
<input
{...register('name', {
required: '名前を入力してね',
minLength: { value: 2, message: `2文字以上にしてね` },
})}
/>
<p>{errors.name?.message}</p> {/* エラー表示 */}
<input type="submit" />
</form>
)
}
どうでしょうか。
input要素にバリデーションルール及びエラー文言をオブジェクトにより指定できて、直感的ではないでしょうか。
送信ボタンを押した際も、event.preventDefault()
も必要がないため、初心者でも躓くことはありません(僕は初め、event.preventDefault`を忘れたことにより、なぜかうまく動作しない!って躓きました。。)。
また、reset()を呼び出すだけで、送信後の入力フォーム欄を初期値に戻すことも簡単です。今回初空白にしていますが、他の値にもできます。
また、watch()関数を利用すことにより、入力の値を常時監視することもできます。useStateを新たに用意する必要もなく、記述量も減ります。便利ですね。
まとめ
今回は、機能のほんの一部のみ紹介しました。
他にも、いつバリデーションをかけるのかなど、バリデーションのための便利な機能がたくさんあります。詳しくは公式ページをご覧ください。
参考
Discussion