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 />;
};
externalProcessing.start() & externalProcessing.end()
Allows to notify the field that some processing 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 externalProcessing.start(). Notify the end of async processing with externalProcessing.end().
const MyField = (props) => {
const { isValidating, externalProcessing } = useField(props);
useEffect(() => {
externalProcessing.start();
getSomeAsyncData().then(() => {
externalProcessing.end();
});
}, [externalProcessing]);
/* ... */
};
Hook values
value
Get the current value of the field, before it has been modified by formatValue
.
Will be undefined
while the form isn't ready, so the field neither.
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, will be equal to value instead).
Will be undefined
while the form isn't ready, so the field neither.
const MyField = (props) => {
const { value, formattedValue, setValue } = useField(props);
return (
<input value={value ?? ""} onChange={e => setValue(e.target.value)}>
);
}
<MyField name="fieldWithFormatValue" formatValue={(value) => `__${value}__`} />
/* Differences between value and formattedValue if value is "value"
{
value: 'value',
formattedValue: '__value__',
}
*/
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);
isDebouncing
Return true
if the field is debouncing async validations.
const { isDebouncing } = 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 returntrue
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 viaformatValue
.
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
: Whentrue
(defaultfalse
) validations will run even on falsy values (includingnull
,undefined
,''
andfalse
).
<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 aPromise
that returntrue
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