Core
useField()

useField

This hooks allows to create a form field.

Import

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

Hook methods

setValue()

Set the value of the field.

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

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

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

setIsTouched()

Set the value isTouched of the field.

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

Hook values

value

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

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

formattedValue

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

const MyField = (props) => {
  const { formatValue, value } = useField(props);
 
  return (
    <input value={value ?? ""} formatValue={(val) => (val || "").replace("a", "e")} />
  );
  /* Differences between value and formattedValue
  {
    value: 'value',
    formattedValue: 'velue',
  }
  */
};

id

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} />
  )
}

isTouched

Return true if the field has been touched.

const { isTouched } = useField(props);

isValid

Return true if the field is valid.

const { isValid } = useField(props);

isValidating

Return true if the field is running async validations.

const { isValidating } = useField(props);

isPristine

Return true if the field has not been changed.

const { isPristine } = useField(props);

isSubmitted

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

const { isSubmitted } = useField(props);

shouldDisplayError

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

const { shouldDisplayError } = useField(props);

errorMessage

Return the first error message.

const { errorMessage } = useField(props);

errorMessages

Return all error messages.

const { errorMessages } = useField(props);

resetKey

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

otherProps

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

name

Required

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',
  },
}
*/

Arrays

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' },
  ],
}
*/

defaultValue

Pass a default value to the field.

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

formatValue(fieldValue)

Format the value before saving it into the internal state.

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

onValueChange(fieldValue)

Function triggered on field value change.

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

required

Shortcut for isRequired() validation.

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

debounceValidationsAsync

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

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

validations

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).
<Field
  name="myFieldName"
  validations={[
    {
      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",
    },
  ]}
/>

validationsAsync

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.
<Field
  name="myFieldName"
  validationsAsync={[
    {
      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".

unstable_notifyOnChangePropsExclusions

Awaiting contribution