This hooks allows to create a form field.


import { useFormFields } from "@formiz/core";

Hook methods


Set the value of the field.

const MyField = (props) => {
  const { setValue } = useField(props);
  return <input onChange={(e) => setValue(} />;

setValue also accepts a function that takes the previous value as a parameter (like React setState).

setValue((previousValue) => {
  // ...
  // Your logic
  // ...
  return newValue;


Set the value isTouched of the field.

const MyField = (props) => {
  const { setIsTouched } = useField(props);
  return <input />;

Hook values


Get the current value of the field, before it has been modified by formatValue.

Will be undefined while field is not register to a ready form.

const MyField = (props) => {
  const { value } = useField(props);
  return <input value={value ?? ""} />;


Get the current value of the field, after it has been formated by formatValue (if you used it).

const MyField = (props) => {
  const { value, formattedValue, setValue } = useField(props);
  return (
    <input value={value ?? ""} onChange={e => setValue(}>
<MyField name="fieldWithFormatValue" formatValue={(value) => `__${value}__`} />
/* Differences between value and formattedValue if value is "value"
  value: 'value',
  formattedValue: '__value__',


Return a unique id. This id will be created based on the form id and the field name.

const MyField = (props) => {
  const { id } = useField(props)
  return (
    <label htmlFor={id}>...</label>
    <input id={id} />


Return true if the field has been touched.

const { isTouched } = useField(props);


Return true if the field is valid.

const { isValid } = useField(props);


Return true if the field is running async validations.

const { isValidating } = useField(props);


Return true if the field has not been changed.

const { isPristine } = useField(props);


Return true either if the current step or the form has been submitted.

const { isSubmitted } = useField(props);


Return true if the field should display an error, useful when debugging.

const { shouldDisplayError } = useField(props);


Return the first error message.

const { errorMessage } = useField(props);


Return all error messages.

const { errorMessages } = useField(props);


Return the number of time the form has been reset.

const { resetKey } = useField(props);
useEffect(() => {
  /* Do a side effect on reset */
}, [resetKey]);

Hook extra values


Get the props passed to the component without the Formiz props. Allows you to keep composition by spreading this object in your component.

type MyFieldProps = FieldProps<unknown> & { styles: CSS.Properties };
const MyField = <FormattedValue = unknown>(
  props: MyFieldProps<FormattedValue>
) => {
  const { otherProps } = useField(props);
  // otherProps type is { styles: CSS.Properties }
  return <div {...otherProps}>{/* your field here */}</div>;

Field props



The name is required to register the field in the form.

<Field name="myFieldName" />

Nested objects

Can use lodash-like dot paths to reference nested values.

<Field name="fieldA" />
<Field name="fieldB" />
<Field name="myGroup.fieldA" />
<Field name="myGroup.fieldB" />
/* Form values
  fieldA: 'value',
  fieldB: 'value',
  myGroup: {
    fieldA: 'value',
    fieldB: 'value',


Also allows arrays out of the box. Using lodash-like bracket syntax for name allows you to handle fields in a list.

<Field name="myArray[0]" />
<Field name="myArray[1]" />
<Field name="myArrayOfObjects[0].fieldA" />
<Field name="myArrayOfObjects[0].fieldB" />
<Field name="myArrayOfObjects[1].fieldA" />
<Field name="myArrayOfObjects[1].fieldB" />
/* Form values
  myArray: ['value', 'value'],
  myArrayOfObjects: [
    { fieldA: 'value', fieldB: 'value' },
    { fieldA: 'value', fieldB: 'value' },


Pass a default value to the field.

<Field name="myFieldName" defaultValue="My initial value" />


Format the value before saving it into the internal state.

<Field name="myFieldName" formatValue={(val) => (val || "").trim()} />


Function triggered on field value change.

<Field name="myFieldName" onValueChange={(val) => console.log(val)} />


Shortcut for isRequired() validation.

<Field name="myFieldName" required="Field is required" />


Number of milliseconds for debouncing validations. (default is 100).

<Field name="myFieldName" debounceValidationsAsync={200} />


Add validation rules that the value needs to fulfill for the field to be considered valid.

Accept an array of object with the following keys:

  • handler(value, rawValue): Built in validation rule or custom validation function (must return true if the rule is valid).
    • value references the value of the field.
    • rawValue references the value of the field before any formatting of the data via formatValue.
  • deps: Array of external values used in the rule function (like array of dependencies in useEffect).
  • message: The message if the rule is invalid.
  • checkFalsy: When true (default false) validations will run even on falsy values (including null, undefined, '' and false).
      handler: isNotEmptyString(),
      message: "Field can't be empty",
      handler: (value) => value.toLowerCase() !== "john",
      message: "Field can't be john",
      handler: (value) => value !== externalValue,
      deps: [externalValue],
      message: "Field can't be the same as external value",


Async validations allows you to run asynchronous code to validate a field, such as an API call. validationsAsync will only be triggered if all the other validations rules are valid.

Accept an array of object with the following keys:

  • handler(fieldValue): Must return a Promise that return true if the rule is valid.
  • deps: Array of external values used in the rule function (like array of dependencies in useEffect).
  • message: The message if the rule is invalid.
      handler: async (value) => {
        const isAlreadyUsed = await validateUsername(value);
        return isAlreadyUsed;
      message: "Username already used, please select another one.",

Field config

Allows to pass default values for useField props.

Available props: "formatValue", "required", "validations", "validationsAsync", "debounceValidationsAsync".


Awaiting contribution