
React Hook Formを使ってきて、慣れてきたので共有です!
目次
- 1. はじめに:useStateでフォーム管理って大変...
- 2. useStateでフォームを作ってみる
- 2-1. シンプルなフォーム例(name / email)
- 2-2. 項目が増えると何が起きる?
- コラム①:Reactとstateについて
- コラム②:制御コンポーネントと非制御コンポーネント
- 3. React Hook Formで同じフォームを書き換える
- 3-1. インストール
- 3-2. 最小構成(register / handleSubmit)
- 4. 何が嬉しいのか(useStateと比べてラクになる点)
- 5. まとめ
1. はじめに:useStateでフォーム管理って大変...
Reactでフォームを作るとき、まずはuseStateで管理することが多いと思います。
ただ、入力項目が増えてくると「stateが増える」「onChangeが増える」「バリデーションが散らかる」など、だんだん辛くなってきます。
今回は、フォームの入力値を管理し、バリデーションも簡単に行えるReact Hook Formを紹介したいと思います。
2. useStateでフォームを作ってみる
コラム①:Reactとstateについて
stateは「コンポーネントが覚えている値」で、stateが更新されると、Reactはコンポーネントを再レンダリング。
フォームをuseStateで管理する場合、入力のたびにstate更新 → 再レンダリングが起きます。
コラム②:制御コンポーネントと非制御コンポーネント
制御コンポーネント(Controlled):valueをstateで(React側で)管理。
非制御コンポーネント(Uncontrolled):値をDOM側で保持し、必要なときにref属性で参照する。
React Hook Formは基本的に非制御として動作。制御コンポーネントとして値を管理することも可能。
2-1. シンプルなフォーム例(name / email)
まずはuseStateを使ったフォームの例です。
名前とメールアドレスを入力するだけのシンプルなものですが、stateを定義していたり、イベントを受け取る関数があったり、inputタグにも色々な属性があったりとシンプルな例でも「ごちゃごちゃ」感がありますよね。
実務では他のロジックのstateもあるので、とても見にくくなります。さらに、GitHub Copilotのようなコード生成AIを使えば、フォーム項目を簡単に追加できてしまいます。その手軽さゆえに、気づけばstateとonChangeハンドラのペアが大量に生成されてしまいます。
TypeScriptimport React, { useState } from "react";
export const SampleFormUseState = () => {
// 管理する値を定義
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// それぞれの状態をコンソールに出力(実際はAPI送信など)
console.log({ name, email });
};
return (
<form onSubmit={handleSubmit}>
<label>
Name
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Taro"
/>
</label>
<label>
Email
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="taro@example.com"
/>
</label>
<button type="submit">Submit</button>
</form>
);
};
2-2. 項目が増えると何が起きる?
- 入力項目ごとにstateが増える
- onChangeが増える(ほぼ同じ処理何度も書く)
- 「ほぼ」というのが共通化しにくくて厄介
- エラー表示やバリデーションを追加すると、さらにstateやロジックが増える
- フォームのstate
- バリデーションエラーのstate
- その他のstate
3. React Hook Formで同じフォームを書き換える
3-1. インストール
まずはインストール!
npm install react-hook-form3-2. 最小構成(register / handleSubmit)
こちらも先ほどの例をReact Hook Formで書き換えたものです。シンプル!綺麗!
register: input などの入力要素をReact Hook Formに登録するための関数。これにより、入力値の追跡やバリデーション(必須入力、文字数制限など)が簡単になる。
TypeScript// 例:必須チェック
<input {...register("name") , { required: true }} placeholder="Taro" />handleSubmit: フォームの送信イベント(onSubmit)でこの関数を使うことで、送信前に自動でバリデーションが実行される。バリデーションが成功した場合にのみ、引数に渡した関数(例では onSubmit)が、フォームのデータ(data)を引数に受け取って実行される。
以下のように第二引数にも関数を渡すことができ、バリデーションエラーが発生した際に実行される。
TypeScript// onError: エラーハンドリング関数
<form onSubmit={handleSubmit(onSubmit, onError)}>TypeScript
import React from "react";
import { useForm } from "react-hook-form";
// フォームで扱う型を定義
type FormData = {
name: string;
email: string;
};
export const SampleFormRHF = () => {
const { register, handleSubmit } = useForm<FormData>();
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>
Name
<input {...register("name")} placeholder="Taro" />
</label>
<label>
Email
<input {...register("email")} placeholder="taro@example.com" />
</label>
<button type="submit">Submit</button>
</form>
);
};
4. 何が嬉しいのか
- 入力項目ごとにuseStateを書かなくてよい
- onChangeハンドラを大量に書かなくてよい
- フォームが大きくなっても管理が破綻しにくい
- 型と入力コンポーネントを追加するだけで良い
- 非制御ベースなので、不要な再レンダリングを抑えやすい
5. まとめ
小さいフォームならuseStateでも十分ですが、項目が増えると途端に管理が大変になります。
React Hook Formは「フォームはフォーム専用ライブラリに任せる」という選択肢を提供してくれるので、実務でもかなり助かります。





![Microsoft Power BI [実践] 入門 ―― BI初心者でもすぐできる! リアルタイム分析・可視化の手引きとリファレンス](/assets/img/banner-power-bi.c9bd875.png)
![Microsoft Power Apps ローコード開発[実践]入門――ノンプログラマーにやさしいアプリ開発の手引きとリファレンス](/assets/img/banner-powerplatform-2.213ebee.png)
![Microsoft PowerPlatformローコード開発[活用]入門 ――現場で使える業務アプリのレシピ集](/assets/img/banner-powerplatform-1.a01c0c2.png)


