Validation
Complex validation behaviors can be achieved combining the Form-level validation and the Field-level validation, controlling when each of those should occur.
#
Form-level validationPass a onValidate
function to useForm()
:
onValidate
receives the values of the form and should return an object whose keys are the field names (with dot notation) and the value is string | string[] | undefined
:
string
in case of a single error messagestring[]
in case of multiple error messagesundefined
means no error
For example:
In this case, name
has no errors and email
has 2 errors.
note
#
Async validationonValidate
can be an async function:
#
DebouncingIn case of async validation (that calls an API, for example), it would be convenient to debounce the validation in order to avoid calling the API too frequently. Pass a validateDebounce
prop to useForm()
:
validateDebounce
is of type: boolean | number | { wait?: number; leading?: boolean }
If you pass:
false
: debounce will not be active (as per default)true
: debounce will be active, with default values forwait
(300) andleading
(false)- a
number
: debounce will be active withwait
as the number you passed, andleading
false - a
{ wait?: number; leading?: boolean }
object: debounce will be active with the values you passed
#
When does form validation run?- When you submit the form.
- When a field value changes - if
validateOnChange
istrue
(true by default). - When a
blur
event occurs - ifvalidateOnBlur
istrue
(false by default). - When you imperatively ask for it - with
form.validate()
.
validateOnChange
and validateOnBlur
are two booleans you can pass to useForm()
:
In this case, validation will run when a blur
event occurs and when the form is submitted.
#
Field-level validationPass a validate
function to useField()
or <Field/>
:
validate
receives the value of the field and the values of the form, and it should return a value of type string | string[] | undefined
.
string
in case of a single error messagestring[]
in case of multiple error messagesundefined
means no error
#
Async validationvalidate
can be an async function:
#
DebouncingSimilarly to form validation you can pass a validateDebounce
value.
#
When does field validation run?- When the form validation runs, also field-level validations run - errors will be merged
- When the field value changes - if
validateOnChange
istrue
(false by default). - When other field values change - if
validateOnChangeFields
is passed. - When the field
blur
event occurs - ifvalidateOnBlur
istrue
(false by default). - When you imperatively ask for it - with
field.validate()
.
validateOnChange
and validateOnBlur
are two booleans you can pass to useField()
(or to <Field />
):
note
Field level's validateOnChange
and validateOnBlur
are independent from Form level's validateOnChange
and validateOnBlur
. You can mix them to achieve different behaviors of validation.
For example you can turn off validateOnChange
and validateOnBlur
on the form, and turn on only validateOnChange
on a specific field. The result will be that the whole form validation will run only on submit, and the validation of that specific field will run while changing the value of the field.
validateOnChangeFields
#
In case your form validation is turned off (form validateOnChange
is false
) but you want your field be validated every time other fields change, then you should use the validateOnChangeFields
options:
In this way, while the user is typing into the email
field, the error appears in the confirmEmail
field, complaining that the two emails are not equal.
note
If you pass a validateOnChangeFields
value that is not undefined
, field's validateOnChange
is automatically considered true
unless you set it to false
.