Skip to main content

useFormStates

useFormStates return the form states as a React state from the form context.

Parameters

useFormStates takes an optional parameter representing the name of the fields to get the states:

  • if nothing is passed then the form state is returned
  • if a string or an array of strings is passed then the related fields states is returned

Returns

useFormStates returns the form React states as an object:

PropertyTypeDescription
changedFieldsstring[]List of fields the user has changed
dirtyFieldsstring[]List of fields the user has changed and values are different to default ones
isChangedbooleanWhether the form/field is changed or not (at least one field is changed)
isDirtybooleanWhether the form/field is dirty or not (at least one field is dirty)
isPristinebooleanInverse of isDirty
isReadybooleanIndicates when the form is ready
isSubmittedbooleantrue when the form has been submitted at least once
isSubmittingbooleanIndicates when the form is being submitted
isValidbooleanWhether the form is valid or not
isValidatingbooleanIndicates when the form is being validated
submitCountnumberCount the number of time the form has been submitted
isTouchedbooleanWhether the form/field is touched or not (at least one field is touched)
touchedFieldsstring[]List of fields the user has interacted with (focus + blur)

All states except isReady reset to initial values when the form is reset.

Usage

0
{
  "changedFields": [],
  "isSubmitting": false,
  "isValid": true,
  "isValidating": false,
  "submitCount": 0,
  "touchedFields": [],
  "isReady": false,
  "dirtyFields": [],
  "isChanged": false,
  "isDirty": false,
  "isPristine": true,
  "isSubmitted": false,
  "isTouched": false
}
import type { FormEvent } from 'react';
import type { IFormValues } from '@per-form/react';
import type { IProps } from '../types';
import { FormProvider, useForm, useFormStates } from '@per-form/react';
import { delay } from '../time';

const defaultValues = { a: 'foo' };
const validator = (value: string) => (values: IFormValues, names: string[]) =>
delay(
String(values[names[0]]).includes(value)
? ''
: `Value does not include "${value}"`,
);
const validators = {
a: validator('foo'),
b: validator('bar'),
c: validator('baz'),
};

function Submit() {
const states = useFormStates();
return (
<>
<div className="actions">
<button disabled={states.isSubmitting} type="submit">
Submit
</button>
<button type="reset">Reset</button>
</div>
<pre>{JSON.stringify(states, null, 2)}</pre>
</>
);
}

export default function Demo(props: IProps) {
function handleSubmit(_e: FormEvent<HTMLFormElement>, values: IFormValues) {
console.log(values);
return delay();
}

const { formProps, ...context } = useForm({
...props,
defaultValues,
onSubmit: handleSubmit,
validators,
});
const { errors } = context;

return (
<FormProvider {...context}>
<form {...formProps}>
<input name="a" required />
{errors.all.a && <div className="error">{errors.all.a}</div>}
<input defaultValue="bar" name="b" required />
{errors.all.b && <div className="error">{errors.all.b}</div>}
<input name="c" required />
{errors.all.c && <div className="error">{errors.all.c}</div>}
<Submit />
</form>
</FormProvider>
);
}