useForm() hook

Use this hook to access values and methods from a <Formiz> component.

Usage from outside <Formiz>

1. Connect your form

import React from 'react'
import { Formiz, useForm } from '@formiz/core'
import { MyField } from './MyField'
export const MyForm = () => {
const myForm = useForm()
return (
<Formiz connect={myForm}>
{/* Your fields here */}
</Formiz>
)
}

2. Access values and methods

You have now access to the form.

import React from 'react'
import { Formiz, useForm } from '@formiz/core'
import { MyField } from './MyField'
export const MyForm = () => {
const myForm = useForm()
return (
<Formiz connect={myForm}>
<form onSubmit={myForm.submit}>
{myForm.isValid && 'The form is valid!'}
{/* Your fields here */}
<button type="submit">
Submit
</button>
<form>
</Formiz>
)
}

Usage from a child component of <Formiz>

import React from 'react'
import { Formiz, useForm } from '@formiz/core'
import { MyField } from './MyField'
export const MySubComponent = () => {
const myForm = useForm()
return myForm.isValid && 'The form is valid!';
}
export const MyForm = () => {
return (
<Formiz>
...
<MySubComponent />
...
</Formiz>
)
}

Hook options

subscribe

TL;DR Use this option for performance optimization only

The subscribe option allows you to tell which part of the internal state you want to subscribe to. By default, you subscribe to the complete internal state. But for performance optimizations, you can choose exactly what you want.

Each time the internal state is updated, the component with the useForm() is updated. With this you can avoid many unecessary rerender and optimize your application by choosing only what you want to subscribe to.

Available values

// Subscribe to form & fields state (default)
useForm()
/* same as */ useForm({ subscribe: true })
/* same as */ useForm({ subscribe: { form: true, fields: true } })
// Subscribe to nothing (only access to form actions)
useForm({ subscribe: false })
/* same as */ useForm({ subscribe: { form: false, fields: false } })
// Subscribe to form state
useForm({ subscribe: 'form' })
/* same as */ useForm({ subscribe: { form: true } })
/* same as */ useForm({ subscribe: { form: true, fields: false } })
// Subscribe to fields state
useForm({ subscribe: 'fields' })
/* same as */ useForm({ subscribe: { fields: true } })
/* same as */ useForm({ subscribe: { form: false, fields: true } })
// Subscribe to form state & only to some fields
useForm({ subscribe: { form: true, fields: ['email', 'password'] } })
// Subscribe only to some fields
useForm({ subscribe: { fields: ['email', 'password'] } })

Subscribe to fields with nested objects and arrays

Imagine the follwing form:

<Formiz>
<Field name="something.collection[0].name" />
<Field name="something.collection[0].email" />
<Field name="something.collection[1].name" />
<Field name="something.collection[1].email" />
<Field name="something.else" />
</Formiz>

You can subscribe like that:

useForm({ subscribe: { fields: ['something.collection[1].name'] } });
/* form.values will returns
{
something: {
collection: [
undefined,
{ name: 'value' },
],
},
}
*/
useForm({ subscribe: { fields: ['something.collection[1]'] } });
/* form.values will returns
{
something: {
collection: [
undefined,
{ name: 'value', email: 'value' },
],
},
}
*/
useForm({ subscribe: { fields: ['something.collection'] } });
/* form.values will returns
{
something: {
collection: [
{ name: 'value', email: 'value' },
{ name: 'value', email: 'value' },
],
},
}
*/
useForm({ subscribe: { fields: ['something'] } });
/* form.values will returns
{
something: {
collection: [
{ name: 'value', email: 'value' },
{ name: 'value', email: 'value' },
],
else: 'value',
},
}
*/

Form actions

The useForm return an object with the following properties:

submit()

Allow you to submit the form

<Formiz connect={myForm}>
<form onSubmit={myForm.submit}>
{/* Your fields here */}
<button type="submit">
Submit
</button>
</form>
</Formiz>

submitStep()

Allows you to submit the current step.

<Formiz connect={myForm}>
<form onSubmit={myForm.submitStep}>
<FormizStep name="step1">
{/* Your fields here */}
</FormizStep>
<FormizStep name="step2">
{/* Your fields here */}
</FormizStep>
<button type="submit">
Submit
</button>
</form>
</Formiz>

invalidateFields(objectOfErrors)

Allow you to invalidate one or many fields.
Useful for API errors or other external errors.

invalidateFields({
'fieldName': 'My error message',
'secondFieldName': 'Another error message',
})

setFieldsValues(objectOfValues, options)

Allow you to change the value of one or many fields imperatively.
Useful to change one or many values based on an external action.

โš ๏ธ Don't use undefined as new value, it will not trigger the update (use null instead).

// Nested values
setFieldsValues({
fieldName: 'New value',
nested: {
subField: 'New value',
},
})
// OR flat values
setFieldsValues({
fieldName: 'New value',
'nested.subField': 'New value',
})

Options

keepUnmounted

Set to true to keep the values of unmounted fields. The values will be used as initial values on the next mount of each fields. (default is false).

// Fields logic
<FieldInput
name="fieldA"
label="Field A"
/>
{form.values?.fieldA === 'hello' && (
<FieldInput
name="fieldB"
label="Field B"
/>
)}
form.setFieldsValues(
{ fieldA: 'hello', fieldB: 'world' },
{ keepUnmounted: true }
)
keepPristine

Set to false to change the isPristine state of updated fields. (default is true).

form.setFieldsValues(
{ fieldA: 'hello', fieldB: 'world' },
{ keepPristine: false }
)

reset(options)

Allows to reset the form with all fields values to their defaultValue.

const myForm = useForm()
myForm.reset() // Trigger the form reset

Options

Available reset elements for the only and exclude options.

'pristine' // Reset isPristine state for form, steps & fields
'submitted' // Reset isSubmitted state for form, steps & fields
'validating' // Reset isValidating state for form, steps & fields
'resetKey' // Increment the resetKey
'currentStep' // Reset the currentStep
'visited' // Reset isVisited state for steps
'values' // Reset all fields values
only

Allows to reset only some elements.

// Reset only pristine state and submitted state
form.reset({ only: ['pristine', 'submitted']ย });
exclude

Allows to prevent reseting some elements.

// Reset everything except the form values
form.reset({ exclude: ['values']ย });

getFieldStepName(fieldName)

Allows you to get the step name of a field.

const myForm = useForm()
const stepNameOfEmail = myForm.getFieldStepName('email')
myForm.goToStep(stepNameOfEmail) // Navigate to the email field step

nextStep()

Move to the next step.

const myForm = useForm()
myForm.nextStep() // Go to the next step

prevStep()

Move to the previous step.

const myForm = useForm()
myForm.prevStep() // Go to the previous step

goToStep(name)

Go to a specific step.

const myForm = useForm()
myForm.goToStep('my-step') // Go to the step with the name 'my-step'

Form state

isValid

Returns true if the form is valid.

const myForm = useForm()
myForm.isValid // true or false

isValidating

Returns true if one field or more is running async validations.

const myForm = useForm()
myForm.isValidating // true or false

isSubmitted

Returns true if the form is submitted.

const myForm = useForm()
myForm.isSubmitted // true or false

resetKey

Allows you to reset some internal state when the form is reset.

const myForm = useForm()
useEffect(() => {
/* Do a side effect on reset */
}, [form.resetKey])

currentStep

Returns the current step object.

// currentStep properties
{
index: number;
name: string;
label?: React.ReactNode;
isCurrent: boolean;
isPristine: boolean;
isValid: boolean;
isValidating: boolean;
isVisited: boolean;
isSubmitted: boolean;
}
const myForm = useForm()
myForm.currentStep?.name // step-name

steps

Returns an array with all the steps of the form.

// Properties for each steps
{
index: number;
name: string;
label?: React.ReactNode;
isCurrent: boolean;
isPristine: boolean;
isValid: boolean;
isValidating: boolean;
isVisited: boolean;
isSubmitted: boolean;
}
const myForm = useForm()
return (
<ul>
{myForm.steps?.map((step) => (
<li key={step.name}>
{step.isValid ? 'โœ…' : 'โŒ'}
{' '}
{step.label || step.name}
</li>
))}
</ul>
)

isStepPristine

Returns true if all the fields are pristine on the current step.

const myForm = useForm()
myForm.isStepPristine // true or false

isStepValid

Returns true if all the fields are valid on the current step.

const myForm = useForm()
myForm.isStepValid // true or false

isStepValidating

Returns true if one field or more is running async validations on the current step.

const myForm = useForm()
myForm.isStepValidating // true or false

isStepSubmitted

Returns true if the current step is submitted.

const myForm = useForm()
myForm.isStepSubmitted // true or false

isFirstStep

Returns true if the current step is the first step.

const myForm = useForm()
myForm.isFirstStep // true or false

isLastStep

Returns true if the current step is the last step.

const myForm = useForm()
myForm.isLastStep // true or false

Fields state

values

Returns an object with all the values of the form with nested values.
See the name props for fields for nested objects and array values.

const myForm = useForm()
myForm.values
/*
{
fieldA: 'field A value',
nested: {
fieldB: 'field B value',
},
collection: [
{ field: 'collection first value'ย },
{ field: 'collection second value'ย },
],
}
*/

flatValues

Returns an object with all the values of the form without nested values.

const myForm = useForm()
myForm.flatValues
/*
{
fieldA: 'field A value',
'nested.fieldB': 'field B value',
'collection[0].field': 'collection first value',
'collection[1].field': 'collection second value',
}
*/

fields

Returns an object with all the fields of the form with their hook values.
See the name props for fields for nested objects and array syntaxe.
See the useField() hook values for available values.

const myForm = useForm()
myForm.fields
/*
{
fieldA: {
errorMessage: 'Required',
isValid: false,
value: 'My value',
// ... All useField hook values
},
nested: {
fieldB: {
// All useField hook values
},
},
collection: [
{
field: {
// All useField hook values
},
},
{
field: {
// useField hook values
},
ย  },
],
}
*/
// Examples
myForm.fields?.fieldA?.isValid
myForm.fields?.nested?.fieldB?.errorMessage
myForm.fields?.collection?.[0]?.field?.isPristine