useFieldArray UseFieldArrayProps
フィールド配列(動的フォーム)を扱うためのカスタムフック。モチベーションは、より良いユーザーエクスペリエンスとパフォーマンスを提供することです。パフォーマンスの向上を視覚化するには、 この短いビデオ をご覧ください。
プロパティ
名前 | 型 | 必須 | 説明 |
---|---|---|---|
name | string | ✓ | フィールド配列の名前。注意:動的な名前はサポートしていません。 |
control | Object | control useForm によって提供されるオブジェクト。FormProviderを使用している場合はオプションです。 | |
shouldUnregister | boolean | アンマウント後にフィールド配列を登録解除するかどうか。 | |
keyName | string = id |
| |
rules | Object | 同じ検証 required、minLength、maxLength、validate
検証エラーが発生した場合、 重要:これは、組み込み検証のみに適用されます。 |
例
function FieldArray() {const { control, register } = useForm();const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({control, // control props comes from useForm (optional: if you are using FormProvider)name: "test", // unique name for your Field Array});return ({fields.map((field, index) => (<inputkey={field.id} // important to include key with field's id{...register(`test.${index}.value`)}/>))});}
戻り値
名前 | 型 | 説明 |
---|---|---|
fields | object &{ id: string } | このobject には、コンポーネントのdefaultValue と key が含まれています。 |
append |
| フィールドの末尾に入力/入力を追加し、フォーカスします。このアクション中に入力値が登録されます。 重要:追加データは必須であり、部分的なものではありません。 |
prepend | (obj: object | object[], focusOptions) => void | フィールドの先頭に入力/入力を追加し、フォーカスします。このアクション中に入力値が登録されます。 重要:prependデータは必須であり、部分的なものではありません。 |
insert | (index: number, value: object | object[], focusOptions) => void | 特定の位置に入力/入力を挿入し、フォーカスします。 重要:挿入データは必須であり、部分的なものではありません。 |
swap |
| 入力/入力の位置を入れ替えます。 |
move |
| 入力/入力を別の位置に移動します。 |
update |
| 特定の位置にある入力/入力を更新します。更新されたフィールドはアンマウントされて再マウントされます。これが望ましくない場合は、 重要:更新データは必須であり、部分的なものではありません。 |
replace |
| フィールド配列全体の値を置き換えます。 |
remove |
| 特定の位置にある入力/入力を削除するか、インデックスが指定されていない場合はすべて削除します。 |
ルール
useFieldArray
は、key
に使用されるid
という名前の一意の識別子を自動的に生成します。prop。これがなぜ必要なのかの詳細については、 https://react.dokyumento.jp/learn/rendering-lists再レンダリングによってフィールドが壊れるのを防ぐために、コンポーネントキーとして
field.id
(index
ではなく)を追加する必要があります。// ✅ correct:{fields.map((field, index) => <input key={field.id} ... />)}// ❌ incorrect:{fields.map((field, index) => <input key={index} ... />)}アクションを次々と積み重ねないことをお勧めします。
onClick={() => {append({ test: 'test' });remove(0);}}// ✅ Better solution: the remove action is happened after the second renderReact.useEffect(() => {remove(0);}, [remove])onClick={() => {append({ test: 'test' });}}各
useFieldArray
は一意であり、独自の状態更新を持っています。つまり、同じname
を持つ複数のuseFieldArrayを持つべきではありません。各入力名は一意である必要があります。同じ名前でチェックボックスまたはラジオを作成する必要がある場合は、
useController
またはController
で使用します。フラットフィールド配列はサポートされていません。
フィールド配列を追加、先頭に追加、挿入、更新する場合、objは空のオブジェクト
ではなく、すべての入力のdefaultValuesを指定する必要があります。
append(); ❌append({}); ❌append({ firstName: 'bill', lastName: 'luo' }); ✅
TypeScript
入力
name
を登録するときは、次のようにキャストする必要があります。const
<input key={field.id} {...register(`test.${index}.test` as const)} />循環参照はサポートされていません。詳細については、こちらの Githubの問題 を参照してください。
ネストされたフィールド配列の場合、その名前でフィールド配列をキャストする必要があります。
const { fields } = useFieldArray({ name: `test.${index}.keyValue` as 'test.0.keyValue' });
例
import React from "react";import { useForm, useFieldArray } from "react-hook-form";function App() {const { register, control, handleSubmit, reset, trigger, setError } = useForm({// defaultValues: {}; you can populate the fields by this attribute});const { fields, append, remove } = useFieldArray({control,name: "test"});return (<form onSubmit={handleSubmit(data => console.log(data))}><ul>{fields.map((item, index) => (<li key={item.id}><input {...register(`test.${index}.firstName`)} /><Controllerrender={({ field }) => <input {...field} />}name={`test.${index}.lastName`}control={control}/><button type="button" onClick={() => remove(index)}>Delete</button></li>))}</ul><buttontype="button"onClick={() => append({ firstName: "bill", lastName: "luo" })}>append</button><input type="submit" /></form>);}
ビデオ
次のビデオでは、基本的な使い方を説明します。 useFieldArray
.
ヒント
カスタム登録
Controller
で入力をregister
することもできます。実際の入力なし。これにより、useFieldArray
は複雑なデータ構造で使用したり、実際のデータが入力内に保存されていない場合でも、すばやく柔軟に使用できるようになります。
import { useForm, useFieldArray, Controller, useWatch } from "react-hook-form";const ConditionalInput = ({ control, index, field }) => {const value = useWatch({name: "test",control});return (<Controllercontrol={control}name={`test.${index}.firstName`}render={({ field }) =>value?.[index]?.checkbox === "on" ? <input {...field} /> : null}/>);};function App() {const { control, register } = useForm();const { fields, append, prepend } = useFieldArray({control,name: "test"});return (<form>{fields.map((field, index) => (<ConditionalInput key={field.id} {...{ control, index, field }} />))}</form>);}
制御されたフィールド配列
フィールド配列全体を制御したい場合があります。つまり、各onChangeがfields
オブジェクトに反映されます。
import { useForm, useFieldArray } from "react-hook-form";export default function App() {const { register, handleSubmit, control, watch } = useForm<FormValues>();const { fields, append } = useFieldArray({control,name: "fieldArray"});const watchFieldArray = watch("fieldArray");const controlledFields = fields.map((field, index) => {return {...field,...watchFieldArray[index]};});return (<form>{controlledFields.map((field, index) => {return <input {...register(`fieldArray.${index}.name` as const)} />;})}</form>);}
ご支援ありがとうございます
React Hook Formがあなたのプロジェクトで役立つ場合は、スターを付けてサポートしてください。