
【React】ReactHookFormのuseFieldArrayで可変フォームの実装
はじめに
この記事の概要
こんにちは、株式会社TOKOSのスギタです!
本日はReactHookFormで実装する可変フォームの紹介をします。
可変フォームでもReactHookFormを使用すればお手軽に実装できてしまいます!
ReactHookFormを使用したことがない方は下記を一度参照することをおすすめします!
React Hook Form - performant, flexible and extensible form library
Performant, flexible and extensible forms with easy-to-use validation.
react-hook-form.com対象読者
- フロントエンドエンジニアの方
- ReactHookFormを使用している方
開発環境
今回はスタイリングはTailwind CSSを使用しています。
今回Tailwind CSSの使用方法は省きます。
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 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を使用していつも通りフォームを実装してください。
今回最終的に取得したいバリューはname:\[{firstName:string,lastName:string}\]ですが一旦通常の単一フォームで実装しています。
名字と名前の入力するフォームを想定しています。
defaultValuesは空文字にしています。
可変フォームの実装
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は必須になっています。
今回はdefaultValuesで初期状態を指定しているため、controlを渡しています。
その他詳細が知りたい方は下記を参照してください。
useFieldArray
Performant, flexible and extensible forms with easy-to-use validation.
react-hook-form.com今回この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が用意されており、とても助かるなという印象です。
可変フォームなど少々複雑でも簡単に実装できてしまい大変助かります!




