Crustack
@crustack/form

Field Arrays

Learn how to manage field arrays.

The FieldArray component simplifies working with arrays of fields as it supports index-based field access (e.g. 'fieldname.0').

To validate the entire array, provide a validate prop to form.FieldArray and place a form.ErrorMessage component below it.

The array is marked as touched when any of its child fields is touched.

1. Basic example

The following example demonstrates a basic usage of the FieldArray component.

import {  } from '@crustack/form'

const  = <{ : string[] }>()

export function () {
  return (
    <.
      ={{ : ['apple', 'banana'] }}
      ={() => 'success'}
    >
      {() => (
        <.>
          <.
            ="fruits"
            // validate the whole field array at once
            ={() =>
              .('pineapple') && 'You must not include pineapple'
            }
          >
            {.('fruits').((, ) => (
              <. ={`fruits.${}`} ={}>
                <.>
                  <
                    ={.(`fruits.${}`)}
                    ={() =>
                      .(`fruits.${}`, ..)
                    }
                  />
                </.>
              </.>
            ))}

            {/* Display the field array error message */}
            <. />
          </.>
        </.>
      )}
    </.>
  )
}

2. With insert / delete

This example demonstrates how to insert and delete items from the array.

import {  } from '@crustack/form'

type  = { : string[]; : string }

const  = <>()

export function () {
  return (
    <.
      ={{ : ['apples', 'meat'], : '' }}
      ={() => 'success'}
    >
      {() => (
        <.>
          <.
            ="items"
            ={() =>
              // validate the entire field array at once
              . < 3 && 'You must have at least 3 items'
            }
          >
            {.('items').((, ) => (
              <. ={`items.${}`} ={}>
                < ={} />

                <
                  ="button"
                  ={() => {
                    // remove the item from the values
                    .('items', () => {
                      const  = [....]
                      .(, 1)
                      return 
                    })
                    // keep the values and touched states in sync
                    .('items', () => {
                      const  = [...(. ?? [])]
                      .(, 1)
                      return 
                    })
                  }}
                >
                  Remove item
                </>
              </.>
            ))}
            {/* The FieldArray's ErrorMessage */}
            <. />
          </.>

          <. ="newItem">
            < ="New Item" />

            <
              ="button"
              ={() => {
                // add the newItem to the items
                .('items', [
                  ....('items'),
                  .('newItem'),
                ])
                // clear the newItem field
                .('newItem', '')
              }}
            >
              Add new Item
            </>
          </.>
        </.>
      )}
    </.>
  )
}

On this page