Skip to content

FieldArray

Render-prop component for working with dynamic field arrays.

</> FieldArray: FieldArrayProps

Component based on the useFieldArray hook, useful for working with dynamic field arrays as a headless/controlled component. All props are the same as useFieldArray, plus a render prop that receives the hook's return value.

<FieldArray
control={control}
name="test"
render={({ fields }) =>
fields.map((field, index) => (
<input key={field.id} {...register(`test.${index}.value`)} />
))
}
/>

Props


NameTypeRequiredDescription
renderFunctionRender prop function that receives the same object useFieldArray returns (fields, append, prepend, insert, remove, swap, move, update, replace) and returns a React element.
namestringName of the field array. Note: Dynamic names are not supported.
controlObjectcontrol object provided by useForm. It's optional if you are using FormProvider.
shouldUnregisterbooleanWhether Field Array will be unregistered after unmount.
disabledbooleanDisables the entire field array. When true, fields initializes as an empty array, all mutation methods (append, prepend, insert, remove, swap, move, update, replace) become no-ops, and the array is not registered with the form. Useful for conditionally enabling a field array in discriminated union form shapes.
keyNamestring = "id"Name of the attribute with autogenerated identifier to use as the key prop. This prop is no longer required and will be removed in the next major version.
rulesObjectThe same validation rules API as for register, which includes: required, minLength, maxLength, validate. In case of validation error, the root property is appended to formState.errors?.fieldArray?.root of type FieldError. Important: This is only applicable to built-in validation.

Return


The following table contains information about the object passed to the render prop function — it's identical to what useFieldArray returns.

NameTypeDescription
fieldsobject & { id: string }This object contains the defaultValue and key for your component. When a field entry includes disabled: true, the disabled attribute is automatically propagated to the registered input.
append(obj: object | object[], focusOptions) => voidAppend input/inputs to the end of your fields and focus. The input value will be registered during this action. Important: append data is required and not partial.
prepend(obj: object | object[], focusOptions) => voidPrepend input/inputs to the start of your fields and focus. The input value will be registered during this action. Important: prepend data is required and not partial.
insert(index: number, value: object | object[], focusOptions) => voidInsert input/inputs at particular position and focus. Important: insert data is required and not partial.
swap(from: number, to: number) => voidSwap input/inputs position.
move(from: number, to: number) => voidMove input/inputs to another position.
update(index: number, obj: object) => voidUpdate input/inputs at a particular position, updated fields will get unmounted and remounted. If this is not desired behavior, please use setValue API instead. Important: update data is required and not partial.
replace(obj: object[]) => voidReplace the entire field array values.
remove(index?: number | number[]) => voidRemove input/inputs at particular position, or remove all when no index provided.
RULES
  • The same rules that apply to useFieldArray apply here — field.id (not index) must be used as the component key, and shouldUnregister: true is not supported.
  • render is called on every render, so keep it free of side effects.
Examples:

import { useForm, FieldArray } from "react-hook-form"
type FormValues = {
test: { value: string }[]
}
export default function App() {
const { control, register, handleSubmit } = useForm<FormValues>({
defaultValues: {
test: [{ value: "" }],
},
})
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<FieldArray
control={control}
name="test"
render={({ fields, append, remove }) => (
<>
{fields.map((field, index) => (
<div key={field.id}>
<input {...register(`test.${index}.value`)} />
<button type="button" onClick={() => remove(index)}>
Delete
</button>
</div>
))}
<button type="button" onClick={() => append({ value: "" })}>
Append
</button>
</>
)}
/>
<input type="submit" />
</form>
)
}

Thank you for your support

If you find React Hook Form to be useful in your project, please consider to star and support it.

Edit