import { useForm } from '@uhg-abyss/web/hooks/useForm';Usage
Default values
The defaultValues prop populates the entire form with default values. It supports both synchronous and asynchronous assignments of default values.
Values
The values props will react to changes and update the form values, which is useful when your form needs to be updated by external state or server data.
// set default value syncfunction App({ values }) { useForm({ values, // will get updated when values props updates });}
function App() { const values = useFetch('/api');
useForm({ defaultValues: { firstName: '', lastName: '', }, values, // will get updated once values returns });}Form state
This object contains information about the form state. If you want to subscribe to formState via useEffect, make sure that you place the entire formState in the optional array.
const form = useForm();
const { errors, // An object with field errors isDirty, // Set to true after the user modifies any of the inputs. isValid, // Set to true if the form doesn't have any errors. isValidating, // Set to true during validation. isSubmitting, // true if the form is currently being submitted; false if otherwise. isSubmitted, // Set to true after the form is submitted. isSubmitSuccessful, // Indicate the form was successfully submitted without any Promise rejection or Error being thrown within the handleSubmit callback. submitCount, // Number of times the form was submitted. touchedFields, // An object containing all the inputs the user has interacted with. dirtyFields, // An object with the user-modified fields.} = form.formState;Watch
This will watch specified inputs and return their values. It is useful for determining what to render.
Handle submit
This function will receive the form data if form validation is successful.
Validate model
This function will receive the model data if form validation is successful.
Reset
Reset either the entire form state or part of the form state.
When invoking reset({ value }) without supplying defaultValues via useForm, the library will replace defaultValues with a shallow clone value object that you provide (not deepClone).
// ❌ avoid the following with deep nested default valuesconst defaultValues = { object: { deepNest: { file: new File() } } };useForm({ defaultValues });reset(defaultValues); // share the same reference
// ✅ it's safer with the following, as we only doing shallow clone with defaultValuesuseForm({ deepNest: { file: new File() } });reset({ deepNest: { file: new File() } });Set error
The function allows you to manually set one or more errors.
Clear errors
This function can manually clear errors in the form.
Set value
This function allows you to dynamically set the value of a registered field. At the same time, it tries to avoid unnecessary re-renders.
Set focus
This method will allow users to programmatically focus on input. Make sure the input's ref is registered in the hook form.
Get values
An optimized helper for reading form values. The difference between watch and getValues is that getValues will not trigger re-renders or subscribe to input changes.
Trigger
Manually triggers form or input validation. This method is also useful when you have dependent validation (input validation depends on another input's value).
Validation strategy
There are two different validation strategies:
mode: Validation strategy before submitting (default:onSubmit).reValidateMode: Validation strategy after submitting (default:onChange).
Teams should only use the following options:
mode:onChange|onSubmitreValidateMode:onChange|onSubmit
Disclaimer: Using other validation strategies can lead to inconsistent behavior.
Cross-field validation example
Form input autofill
Autofill off
Additional documentation
@uhg-abyss/web/hooks/useForm is a built on top of the useForm hook from React Form Hook.
Teams that already leverage or want to use React Hook Form in other spots in your application can use the @uhg-abyss/web/tools/reactHookFormTools package.
This package can ensure you are using the same version of React Hook Form across your application and can also be used to grab type information directly. Here is an example below:
**Note: ** You should be using Abyss's useForm hook when using Abyss componenets and not react hook forms.
import { SubmitHandler } from '@uhg-abyss/web/tools/reactHookFormTools';
interface FormData { firstName: string;}///...const handleSubmit: SubmitHandler<FormData> = (data) => { console.log('data', data);};///...Using TypeScript with useForm gives you strong type checking for your form data structure. Here's a example:
interface FormData { firstName: string; lastName: string;}
const form = useForm<FormData>({ defaultValues: { firstName: '', lastName: '', pizza: 'cheese', // Throws TS error since pizza is not a field in FormData },});
// Throws TS error since pizza is not a field in FormDataconst WatchField = form.watch('pizza');
// Doesn't throw TS error since firstName and lastName are fields in FormDataconst WatchFields = form.watch(['firstName', 'lastName']);