useField() hook

Concept

When using the useField hook, you need to pass your component props to the hook.

Then the hook gives you access to the field state.

import React from 'react'
import { useField } from '@formiz/core'
const MyField = (props) => {
const {
value,
setValue,
isValid,
errorMessage,
} = useField(props)
return (
...
)
}

Hooks 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 accept a function that gives the previous value (like React setState).

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

validating.start() & validating.end()

Allows to notify the field that some validations are done in the background (like retrieving some data).

This will update the isValidating state at the field level and also at the form and step levels.

Notify the start of async processing with validating.start(). Notify the end of async processing with validating.end().

const MyField = (props) => {
const { isValidating, validating } = useField(props);
useEffect(() => {
validating.start();
getSomeAsyncData().then(() => {
validating.end();
});
}, [validating]);
/* ... */
}

Hook values

value

Get the current value of the field.

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

valueDebounced

Get the current value of the field, but sync with the debouncing. It can be useful to determinate when to show error messages.

const { valueDebounced } = useField(props)

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

isValid

Returns true if the field is valid.

const { isValid } = useField(props)

isValidating

Returns true if the field is running async validation or after validating.start() is called (until validation.end() is called).

const { isValidating } = useField(props)

isPristine

Returns true if the field has not been changed.

const { isPristine } = useField(props)

isSubmitted

Returns true either if the current step or the form is submitted.

const { isSubmitted } = useField(props)

errorMessage

Returns the first error message.

const { errorMessage } = useField(props)

errorMessages

Returns all error messages.

const { errorMessages } = useField(props)

resetKey

Allows you to put a key on elements that you want to be reinitialize when the from is reset.
Can be useful for element like <input> or <select>.

const MyField = (props) => {
const { resetKey } = useField(props)
useEffect(() => {
/* Do something on reset */
}, [resetKey])
return <input key={resetKey} />
}

Hook extra values

This values are not available in the useForm() fields object.

otherProps

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

const MyField = (props) => {
const { otherProps } = useField(props)
return (
<Box {...otherProps}>
{/* Field */}
</Box>
)
}

Field props

When a component is created with the useField() hook, you can pass the following props to the component.

name *

Required

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

<Field name="myFieldName" />

Nested objects

The name props 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

The name props allow also arrays and arrays of objects out of the box. Using lodash-like bracket syntax for name allow 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' },
],
}
*/

debounce

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

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

defaultValue

Pass an initial value to the field.

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

keepValue

Set to true to keep the value when the field is unmounted from the DOM. (default is false).

<Field name="myFieldName" keepValue />

formatValue(fieldValue)

Format the value before saving it into the internal state.

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

onChange(fieldValue)

Triggered everytime that setValue() is called inside the field.

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

required

Shortcut for isRequired() validation

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

validations

Accept an array of object with the following keys:

  • rule(fieldValue): Built in validation rule or custom validation function (must returns 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"
validations={[
{
rule: isRequired(),
message: 'Field is required',
},
{
rule: isNotEmptyString(),
message: 'Field can\'t be empty',
},
{
rule: (value) => value.toLowerCase() !== 'john',
message: 'Field can\'t be john',
},
{
rule: (value) => value !== externalValue,
deps: [externalValue],
message: 'Field can\'t be the same as external value',
},
]}
/>

asyncValidations

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

Accept an array of object with the following keys:

  • rule(fieldValue): Must returns a Promise that returns 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"
asyncValidations={[
{
rule: async(value) => {
const isAlreadyUsed = await validateUsername(value)
return isAlreadyUsed;
},
message: 'Username already used, please select another one.',
}
]}
/>

PropTypes validations

If you are using prop-types to document props in your project, you can get fieldPropTypes and fieldDefaultProps from @formiz/core to pass to your custom fields for PropTypes validations.

// MyField.js
import React from 'react'
import { useField, fieldPropTypes, fieldDefaultProps } from '@formiz/core'
const MyField = (props) => {
// ...
}
MyField.propTypes = {
...fieldPropTypes,
// Your custom props
}
MyField.defaultProps = {
...fieldDefaultProps,
// Your custom props
}