はじめに
この記事の概要
こんにちは、株式会社TOKOSのスギタです!
本日はReactHookFormで実装する可変フォームの紹介をします。
可変フォームでもReactHookFormを使用すれば簡単にお手軽に実装できてしまいます!
ReactHookFormを使用したことがない方は下記を一度参照することをおすすめします!
対象読者
- フロントエンドエンジニアの方
- ReactHookFormを使用している方
開発環境
今回はスタイリングはtailwindを使用しています。
今回tailwindの使用方法は省きます
- react-hook-form: “^7.51.5”,
- react: “^18”,
- tailwindcss: “^3.4.1”,
- typescript: “^5”
実装完了予定
今回入力フォームが増減するフォームを作成していきたいと思います。
今回の完成予定は下記になります。
このように可変するフォームを作成していこうと思います。
早速コードの紹介です。
useFormの使用
export default function ExamplePage() {
const { register, control, handleSubmit } = useForm({
defaultValues: {
name: { firstName: "", lastName: "" },
},
})
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<ul className="flex flex-col gap-2">
<li key={item.id} className="flex gap-2">
<input {...register("name.firstName"} className="border border-black" />
<input {...register("name.lastName"} className="border border-black" />
</li>
</ul>
<button type="submit" className="mt-2 w-[300px] bg-blue-500 p-2 text-white">
送信
</button>
</form>
)
}
まずはuseFormを使用していつも通りフォームを実装してください。
今回最終的な取得したいバリューはtest:[{firstName:string,lastName:string}]ですが一旦通常の単一フォームで実装しています。
名字と名前の入力するフォームを想定しています。
defaultValueは空文字にしています。
可変フォームの実装
React Hook Formで可変フォームを実現するにはuseFieldArray を使用しなければなりません。
最終的な取得したい値が配列で要素数が可変させたい場合に使用します!
export default function ExamplePage() {
const { register, control, handleSubmit } = useForm({
defaultValues: {
name: [{ firstName: "", lastName: "" }],
},
})
const { fields, append, remove } = useFieldArray({
control,
name: "name",
})
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<button
className="mb-3 w-[300px] bg-green-500 p-2 text-white"
type="button"
onClick={() => append({ firstName: "", lastName: "" })}
>
追加する
</button>
<ul className="flex flex-col gap-2">
{fields.map((item, index) => (
<li key={item.id} className="flex gap-2">
<input {...register(`name.${index}.firstName`)} className="border border-black" />
<input {...register(`name.${index}.lastName`)} className="border border-black" />
<button
className="bg-red-500 p-2 text-white"
type="button"
onClick={() => remove(index)}
>
削除する
</button>
</li>
))}
</ul>
<button type="submit" className="mt-2 w-[300px] bg-blue-500 p-2 text-white">
送信
</button>
</form>
)
}
useFieldArrayを呼びだします。
引数にはcontrolとnameを渡します。
controlはuseFormを使用している場合は必須で、nameは必須になっています。
今回デフォルトバリューを使用して初期状態を指定しているため、controlは必須になります。
その他詳細が知りたい方は下記を参照してください。
今回このuseFieldArrayのfieldsが重要になってきます。
可変させたいフォームをfieldsで繰り返し処理(map)することにより、可変フォーム化することができます。
map処理の第二引数のindexをregisterのname属性に渡し、一意なnameにすることにより可変フォーム化するということです。
またuseFieldArrayにメソッドが用意されております。
追加する(append)や削除(remove)これらを使用することで配列内の要素を増減することができます。
appendやremoveの他にも配列内の要素を扱うためのメッソドが用意されております。
append | フィールドの最後(配列の最後)に指定したデータを追加してフォーカスします。 |
remove | 特定の位置(index)にある入力を削除します。 |
prepend | フィールドの先頭(配列の最初)に指定したデータを追加してフォーカスします。 |
insert | 特定の位置(index)に指定したデータを追加してフォーカスします。 |
swap | 位置の入れ替え |
move | 指定した位置に移動 |
update | 特定の位置で入力を更新すると、更新されたフィールドはマウント解除され、再マウントされます。 |
replace | 配列の値全体を置き換え |
このように実装条件により、様々なメソッドを選択することができます。
通常の可変フォームですと、appendとremoveを使用すれば問題ないかと思います!
さいごに
今回はReactHookFormで可変フォームを作成してみました。
やはりReactHookFormは様々なHookが用意されており、とても助かるなという印象です。
可変フォームなど少々複雑でも簡単に実装できていまい大変助かります!