React Hook Formの基本機能
1. インストール&インポート
> npm install react-hook-form
# または
> yarn add react-hook-form
import { useForm } from "react-hook-form";
2. フォームの初期化
- defaultValuesで初期値の設定
- useFormでフォームの初期化
- register 入力要素にハンドラーなどを登録する
- handleSubmit サブミット時に使用する
- formState: { errors } エラー状態を取得する
- defaultValues 初期値を設定する
const defaultValues = {
name: "",
email: "",
gender: "male",
country: "japan",
agree: false,
memo: "",
};
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues,
});
3. FormのonSubmit設定
-
onSubmit=handleSubmit(onsubmit, onerror)
-
noValidate
ブラウザによるデフォルトのフォーム入力検証を無効
-
-
onsubmit
検証成功時の処理 -
onerror
検証失敗時の処理
<form onSubmit={handleSubmit(onsubmit, onerror)} noValidate>
{/* 入力要素... */}
<button type="submit">送信</button>
</form>
const onsubmit = (data) => console.log(data);
const onerror = (err) => console.log(err);
4. 入力要素にregisterをスプレッド演算子で展開する(フィールド名, 検証ルールなど)
- 基本 register(フィールド名)をinputタグに入れる
...register("name")
- バリデーション
{required: "必須メッセージ", maxLength: {value: 20, message: "文字数メッセージ"}}
- エラー表示部分
{errors.name && <div>{errors.name.message}</div>}
<div>
<label htmlFor="name">名前:</label>
<input
id="name"
type="text"
// registerをスプレッド演算子で展開する(フィールド名, 検証ルールなど)
{...register("name", {
required: "名前は必須入力です。",
maxLength: {
value: 20,
message: "名前は20文字以内にしてください",
},
})}
/>
{errors.name && <div>{errors.name.message}</div>}
</div>
ソース全体
import { useForm } from "react-hook-form";
export default function FormBasic() {
const defaultValues = {
name: "",
email: "",
gender: "male",
country: "japan",
agree: false,
memo: "",
};
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues,
});
const onSubmit = (data) => console.log(data);
const onError = (errors) => console.log(errors);
return (
<div>
<form onSubmit={handleSubmit(onSubmit, onError)} noValidate>
<div>
<label htmlFor="name">名前:</label>
<input
id="name"
type="text"
{...register("name", {
required: "名前は必須入力です。",
maxLength: {
value: 20,
message: "名前は20文字以内にしてください",
},
})}
/>
{errors.name && <div role="alert">{errors.name.message}</div>}
</div>
<div>
<label htmlFor="gender">性別:</label>
<div>
<label>
<input
type="radio"
value="male"
{...register("gender", {
required: "性別は必須です。",
})}
/>
男性
</label>
<label>
<input
type="radio"
value="female"
{...register("gender", {
required: "性別は必須です。",
})}
/>
女性
</label>
</div>
{errors.gender && <div role="alert">{errors.gender.message}</div>}
</div>
<div>
<label htmlFor="country">国籍:</label>
<select
id="country"
{...register("country", {
required: "国籍を選択してください。",
})}
>
<option value="">選択してください</option>
<option value="japan">日本</option>
<option value="usa">アメリカ</option>
<option value="china">中国</option>
<option value="other">その他</option>
</select>
{errors.country && <div role="alert">{errors.country.message}</div>}
</div>
<div>
<label htmlFor="email">メールアドレス:</label>
<input
id="email"
type="email"
{...register("email", {
required: "メールアドレスは必須入力です。",
pattern: {
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: "メールアドレスの形式が不正です。",
},
})}
/>
{errors.email && <div role="alert">{errors.email.message}</div>}
</div>
<div>
<label htmlFor="agree">
<input
id="agree"
type="checkbox"
{...register("agree", {
required: "利用規約に同意してください。",
})}
/>
利用規約に同意する
</label>
{errors.agree && <div role="alert">{errors.agree.message}</div>}
</div>
<div>
<label htmlFor="memo">備考:</label>
<textarea
id="memo"
{...register("memo", {
required: "備考は必須入力です。",
minLength: {
value: 10,
message: "備考は10文字以上にしてください",
},
})}
/>
{errors.memo && <div role="alert">{errors.memo.message}</div>}
</div>
<div>
<button type="submit">送信</button>
</div>
</form>
</div>
);
}
動作画面
続き