💰 **Wanna get paid the big bucks writing React? [Take this quiz](https://triplebyte.com/a/V6j0KPS/rffarrays) and get offers from top tech companies!** 💰 --- # 🏁 React Final Form Arrays [![NPM Version](https://img.shields.io/npm/v/react-final-form-arrays.svg?style=flat)](https://www.npmjs.com/package/react-final-form-arrays) [![NPM Downloads](https://img.shields.io/npm/dm/react-final-form-arrays.svg?style=flat)](https://www.npmjs.com/package/react-final-form-arrays) [![Build Status](https://travis-ci.org/final-form/react-final-form-arrays.svg?branch=master)](https://travis-ci.org/final-form/react-final-form-arrays) [![codecov.io](https://codecov.io/gh/final-form/react-final-form-arrays/branch/master/graph/badge.svg)](https://codecov.io/gh/final-form/react-final-form-arrays) [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) --- ## Installation ```bash npm install --save react-final-form-arrays react-final-form final-form final-form-arrays ``` or ```bash yarn add react-final-form-arrays react-final-form final-form final-form-arrays ``` ## Usage 🏁 React Final Form Arrays provides a way to render arrays in 🏁 React Final Form. ```jsx import { Form, Field } from 'react-final-form' import arrayMutators from 'final-form-arrays' import { FieldArray } from 'react-final-form-arrays' const MyForm = () => (
( {({ fields }) => (
{fields.map((name, index) => (
))}
)}
)} /> ) ``` ## Table of Contents - [Examples](#examples) - [Simple Example](#simple-example) - [React Beautiful DnD Example](#react-beautiful-dnd-example) - [Rendering](#rendering) - [API](#api) - [`FieldArray : React.ComponentType`](#fieldarray--reactcomponenttypefieldarrayprops) - [`useFieldArray`](#usefieldarray) - [`version: string`](#version-string) - [Types](#types) - [`FieldArrayProps`](#fieldarrayprops) - [`children?: ((props: FieldArrayRenderProps) => React.Node) | React.Node`](#children-props-fieldarrayrenderprops--reactnode--reactnode) - [`component?: React.ComponentType`](#component-reactcomponenttypefieldarrayrenderprops) - [`name: string`](#name-string) - [`render?: (props: FieldArrayRenderProps) => React.Node`](#render-props-fieldarrayrenderprops--reactnode) - [`defaultValue?: any`](#defaultvalue-any) - [`initialValue?: any`](#initialvalue-any) - [`isEqual?: (allPreviousValues: Array, allNewValues: Array) => boolean`](#isequal-allpreviousvalues-arrayany-allnewvalues-arrayany--boolean) - [`subscription?: FieldSubscription`](#subscription-fieldsubscription) - [`validate?: (value: ?any[], allValues: Object) => ?any`](#validate-value-any-allvalues-object--any) - [`FieldArrayRenderProps`](#fieldarrayrenderprops) - [`fields.forEach: (iterator: (name: string, index: number) => void) => void`](#fieldsforeach-iterator-name-string-index-number--void--void) - [`fields.insert: (index: number, value: any) => void`](#fieldsinsert-index-number-value-any--void) - [`fields.map: (iterator: (name: string, index: number) => any) => any[]`](#fieldsmap-iterator-name-string-index-number--any--any) - [`fields.move: (from: number, to: number) => void`](#fieldsmove-from-number-to-number--void) - [`fields.name: string`](#fieldsname-string) - [`fields.pop: () => any`](#fieldspop---any) - [`fields.push: (value: any) => void`](#fieldspush-value-any--void) - [`fields.remove: (index: number) => any`](#fieldsremove-index-number--any) - [`fields.shift: () => any`](#fieldsshift---any) - [`fields.swap: (indexA: number, indexB: number) => void`](#fieldsswap-indexa-number-indexb-number--void) - [`fields.update: (index: number, value: any) => void`](#fieldsupdate-index-number-value-any--void) - [`fields.unshift: (value: any) => void`](#fieldsunshift-value-any--void) - [`meta.active?: boolean`](#metaactive-boolean) - [`meta.data: Object`](#metadata-object) - [`meta.dirty?: boolean`](#metadirty-boolean) - [`meta.error?: any`](#metaerror-any) - [`meta.initial?: any`](#metainitial-any) - [`meta.invalid?: boolean`](#metainvalid-boolean) - [`meta.pristine?: boolean`](#metapristine-boolean) - [`meta.submitError?: any`](#metasubmiterror-any) - [`meta.submitFailed?: boolean`](#metasubmitfailed-boolean) - [`meta.submitSucceeded?: boolean`](#metasubmitsucceeded-boolean) - [`meta.touched?: boolean`](#metatouched-boolean) - [`meta.valid?: boolean`](#metavalid-boolean) - [`meta.visited?: boolean`](#metavisited-boolean) ## Examples ### [Simple Example](https://codesandbox.io/s/kx8qv67nk5) Demostrates how to use `` to render an array of inputs, as well as use `push`, `pop`, and `remove` mutations. ### [React Beautiful DnD Example](https://codesandbox.io/s/8k0ykyr7z9) Demostrates how to integrate the simple example with [react-beautiful-dnd](https://github.com/atlassian/react-beautiful-dnd) ## Rendering There are three ways to tell `` what to render: | Method | How it is rendered | | ------------------------------- | --------------------------------------------------------- | | `component` prop | `return React.createElement(this.props.component, props)` | | `render` prop | `return this.props.render(props)` | | a render function as `children` | `return this.props.children(props)` | ## API The following can be imported from `react-final-form-arrays`. ### `FieldArray : React.ComponentType` A component that takes [`FieldArrayProps`](#fieldarrayprops) and renders an array of fields ### `useFieldArray` The `useFieldArray` hook takes two parameters, the first is the name of the field, and the second is an optional object that looks just like [`FieldArrayProps`](#fieldarrayprops), except without the name. It returns an object just like [`FieldArrayRenderProps`](#fieldarrayrenderprops). `useFieldArray` is used interally inside `FieldArray`. ### `version: string` The current used version of 🏁 React Final Form Arrays. --- ## Types ### `FieldArrayProps` These are props that you pass to [``](#fieldarray--reactcomponenttypefieldarrayprops). You must provide one of the ways to render: `component`, `render`, or `children`. #### `children?: ((props: FieldArrayRenderProps) => React.Node) | React.Node` A render function that is given [`FieldArrayRenderProps`](#fieldarrayrenderprops), as well as any non-API props passed into the `` component. #### `component?: React.ComponentType` A component that is given [`FieldArrayRenderProps`](#fieldarrayrenderprops) as props, as well as any non-API props passed into the `` component. #### `name: string` The name of your field array. #### `render?: (props: FieldArrayRenderProps) => React.Node` A render function that is given [`FieldArrayRenderProps`](#fieldarrayrenderprops), as well as any non-API props passed into the `` component. #### `defaultValue?: any` ⚠️ You probably want `initialValue`! ⚠️ _**Before using this prop, read and understand the 🏁 Final Form documentation on [`initialValue`](https://github.com/final-form/final-form#initialvalue-any) and [`defaultValue`](https://github.com/final-form/final-form#defaultvalue-any)!**_ #### `initialValue?: any` [See the 🏁 Final Form docs on `initialValue`](https://github.com/final-form/final-form#initialvalue-any) #### `isEqual?: (allPreviousValues: Array, allNewValues: Array) => boolean` A function that can be used to compare two arrays of values (before and after every change) and calculate pristine/dirty checks. Defaults to a function that will `===` check each element of the array. #### `subscription?: FieldSubscription` A [`FieldSubscription`](https://github.com/final-form/final-form#fieldsubscription--string-boolean-) that selects of all the items of [`FieldState`](https://github.com/final-form/final-form#fieldstate) that you wish to update for. If you don't pass a `subscription` prop, it defaults to _all_ of [`FieldState`](https://github.com/final-form/final-form#fieldstate). #### `validate?: (value: ?any[], allValues: Object) => ?any` A function that takes the field value, and all the values of the form and returns an error if the array value is invalid, or `undefined` if the value is valid. ### `FieldArrayRenderProps` These are the props that [``](#fieldarray--reactcomponenttypefieldarrayprops) provides to your render function or component. This object is divided into a `fields` object that mimics an iterable (e.g. it has `map()` and `forEach()` and `length`), and `meta` data about the field array. Keep in mind that **the values in `meta` are dependent on you having subscribed to them** with the [`subscription` prop](#subscription-fieldsubscription) #### `fields.forEach: (iterator: (name: string, index: number) => void) => void` Iterates through all of the names of the fields in the field array in bracket format, e.g. `foo[0]`, `foo[1]`, `foo[2]`. #### `fields.insert: (index: number, value: any) => void` A function to insert a value into any arbitrary index of the array. #### `fields.map: (iterator: (name: string, index: number) => any) => any[]` Iterates through all of the names of the fields in the field array in bracket format, e.g. `foo[0]`, `foo[1]`, `foo[2]`, and collects the results of the iterator function. You will use this in almost every implementation. #### `fields.move: (from: number, to: number) => void` A function to move a value from one index to another. Useful for drag-and-drop reordering. #### `fields.name: string` The name of the field array. #### `fields.pop: () => any` A function to remove a value from the end of the array. The value will be returned. #### `fields.push: (value: any) => void` A function to add a value to the end of the array. #### `fields.remove: (index: number) => any` A function to remove a value from an arbitrary index of the array. #### `fields.shift: () => any` A function to remove a value from the beginning of the array. The value will be returned. #### `fields.swap: (indexA: number, indexB: number) => void` A function to swap two values in the array. #### `fields.update: (index: number, value: any) => void` Updates a value of the specified index of the array field. #### `fields.unshift: (value: any) => void` A function to add a value to the beginning of the array. #### `fields.value: any[]` The value of the array. Should be treated as readonly. #### `meta.active?: boolean` [See the 🏁 Final Form docs on `active`](https://github.com/final-form/final-form#active-boolean). #### `meta.data: Object` [See the 🏁 Final Form docs on `data`](https://github.com/final-form/final-form#data-object). #### `meta.dirty?: boolean` [See the 🏁 Final Form docs on `dirty`](https://github.com/final-form/final-form#dirty-boolean). #### `meta.error?: any` [See the 🏁 Final Form docs on `error`](https://github.com/final-form/final-form#error-any). #### `meta.initial?: any` [See the 🏁 Final Form docs on `initial`](https://github.com/final-form/final-form#initial-any). #### `meta.invalid?: boolean` [See the 🏁 Final Form docs on `invalid`](https://github.com/final-form/final-form#invalid-boolean). #### `meta.pristine?: boolean` [See the 🏁 Final Form docs on `pristine`](https://github.com/final-form/final-form#pristine-boolean). #### `meta.submitError?: any` [See the 🏁 Final Form docs on `submitError`](https://github.com/final-form/final-form#submiterror-any). #### `meta.submitFailed?: boolean` [See the 🏁 Final Form docs on `submitFailed`](https://github.com/final-form/final-form#submitfailed-boolean). #### `meta.submitSucceeded?: boolean` [See the 🏁 Final Form docs on `submitSucceeded`](https://github.com/final-form/final-form#submitsucceeded-boolean). #### `meta.touched?: boolean` [See the 🏁 Final Form docs on `touched`](https://github.com/final-form/final-form#touched-boolean). #### `meta.valid?: boolean` [See the 🏁 Final Form docs on `valid`](https://github.com/final-form/final-form#valid-boolean). #### `meta.visited?: boolean` [See the 🏁 Final Form docs on `visited`](https://github.com/final-form/final-form#visited-boolean).