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 validation#
Pass 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:
stringin case of a single error messagestring[]in case of multiple error messagesundefinedmeans no error
For example:
In this case, name has no errors and email has 2 errors.
note
Async validation#
onValidate can be an async function:
Debouncing#
In 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 withwaitas the number you passed, andleadingfalse - 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
validateOnChangeistrue(true by default). - When a
blurevent occurs - ifvalidateOnBluristrue(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 validation#
Pass 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.
stringin case of a single error messagestring[]in case of multiple error messagesundefinedmeans no error
Async validation#
validate can be an async function:
Debouncing#
Similarly 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
validateOnChangeistrue(false by default). - When other field values change - if
validateOnChangeFieldsis passed. - When the field
blurevent occurs - ifvalidateOnBluristrue(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.