Nested Fields

{
  "name": {
    "firstname": "John",
    "lastname": "Doe"
  }
}
{
  "items": "should have more than 1 items"
}
Form Invalid

TIP: Open react developer tools, go to preferences and enable Highlight updates and then start typing on the form inputs to see which components update.

Code

import React, { useState } from 'react'
import { useForm } from 'react-form-hooks'

import { Input } from '../recipes/Components'
import FormField from '../recipes/FormField'
import ArrayFormField from '../recipes/ArrayFormField'
import FormFooter from '../recipes/FormFooter'

export default function NestedForm() {
  const [values, setValues] = useState({
    name: {
      firstname: 'John',
      lastname: 'Doe',
    },
  })
  const defaultValues = {
    name: {
      firstname: 'John',
      lastname: 'Doe',
    },
    items: [1, 2],
    itemsObj: [
      {
        title: 'My title',
        description: 'My desc',
      },
    ],
    email: 'form@email.me',
  }
  const changeValues = () => setValues(defaultValues)
  const onSubmit = values => alert(JSON.stringify(values, null, 2))
  const form = useForm({ initialValues: values })
  console.log('FORM_RERENDER')

  return (
    <form
      className="form-horizontal"
      onSubmit={form.formActions.submitHandler(onSubmit)}
    >
      <FormField
        form={form}
        id="name.firstname"
        label="Firstname"
        component={Input}
        validate={value => {
          return /\d/.test(value) && 'should not contain a number'
        }}
        onChange={value => {
          return value.toUpperCase()
        }}
      />
      <FormField
        form={form}
        id="name.lastname"
        label="Lastname"
        component={Input}
      />
      <FormField
        form={form}
        id="email"
        label="Email"
        component={Input}
        validate={value => /\d/.test(value) && 'should not contain a number'}
      />
      <ArrayFormField
        form={form}
        id="items"
        label="Items"
        validate={value => value.length < 2 && 'should have more than 1 items'}
        InputProps={{
          renderField: (id, index) => (
            <FormField
              form={form}
              id={id}
              label={`Item ${index}`}
              component={Input}
              validate={value => value <= 10 && 'should be greater than 10'}
              InputProps={{
                type: 'number',
              }}
            />
          ),
        }}
      />
      <ArrayFormField
        form={form}
        id="itemsObj"
        label="Items Object"
        InputProps={{
          renderField: (id, index) => (
            <>
              <FormField
                form={form}
                id={`${id}.title`}
                label={`Title ${index}`}
                component={Input}
              />
              <FormField
                form={form}
                id={`${id}.description`}
                label={`Description ${index}`}
                component={Input}
              />
            </>
          ),
        }}
      />

      <FormFooter form={form} resetToNewValues={changeValues} />
    </form>
  )
}