よくある、入力フォームで性別を選択してもらう
あれ実装したいと思いました。
初めてReact Hook Formを使って実装しようと思ったのですが、
ちょっと迷走したので解決方法をここにメモしておきます。
(スタイルはまだ当てていません)
公式ドキュメント:https://react-hook-form.com/get-started/
やりたいこと
(まずはお試しということで、男女だけで実装します)
- ラベルは「男」「女」、
送信される値は男なら「1」女なら「2」 - ラベルを選択してもチェックがつく
- 必須項目とする
困ったこと
必須項目にしたいけど、どうやって設定すればいいかわからない😫
そもそもどの要素にrequiredを設定すればいいかわかっていませんでした。
検索してみると、requiredはinput自身に設定するようです。
(複数あるうちの一つにrequired: trueが設定されていればOK)
ただ、今後性別の項目が増えることを考慮して
map関数で繰り返し処理を行いHTMLを出力していたので、
「required属性を記述すると全てのinputにrequiredが設定されてしまう…!」
とかなり迷走しました。
//当初のコード
const radioButtons = [
{ id: "male", label: "👨男", value: 1 },
{ id: "female", label: "👩女", value: 2 },
];
{radioButtons.map((radio) => {
const { id, label, value } = radio;
return (
<label key={id}>
<input
type="radio"
value={value}
name="gender-group"
// この記述では全てのinputタグにrequiredが設定される
{...(register("gender"), { required: true })}
/>
{label}
</label>
);
})}
解決方法
解決方法は単純で、map関数で繰り返す対象の配列に
requiredの項目を追加すればよいのです…!
const radioButtons = [
{ id: "male", label: "👨男", value: 1, required: true },
{ id: "female", label: "👩女", value: 2, required: false },
];
{radioButtons.map((radio) => {
const { id, label, value, required } = radio;
return (
<label key={id}>
<input
type="radio"
value={value}
name="gender-group"
{...register("gender", { required })}
/>
{label}
</label>
);
})}
両方クリックしたら、両方にチェックがつく😫
name属性が設定できていなかった
エラー等なにも出ていなかったのですが、
単純に記述ミスをしており、name属性が設定されていませんでした😭
name属性を設定しないと、複数あるinputが
それぞれ独立したタグだと認識されるため、両方にチェックがついてしまいます。
name属性で同じ名前が付与されているinputタグは
同じグループであると認識されます。
//間違い
<input
type="radio"
value={value}
//registerの第二引数として渡せていません
{...register("gender"), { required, name: "gender-group" }}
/>
// 正しい
<input
type="radio"
value={value}
{...(register("gender"), { required, name: "gender-group" })}
/>
registerの引数を正しく記述すれば、React Hook Formが自動的にname属性を設定してくれます。
registerに関する公式ドキュメント:https://legacy.react-hook-form.com/api/useform/register
それでは!
コメント