useForm
is a React hook that returns several properties to validate and manage the state of form fields in UI Kit. For full examples on how to use this hook with UI Kit components,
see the Form component.
To import useForm
into your app:
1 2import { useForm } from '@forge/react';
Props
Name | Type | Required | Description |
---|---|---|---|
defaultValues | FieldValues | No | Default values for the form. |
The defaultValues
prop populates the entire form with default values. It is recommended to use defaultValues
for the entire form.
1 2useForm({ defaultValues: { firstName: '', lastName: '' } })
undefined
as a default value, as it conflicts with the default state of controlled components.defaultValues
will be included in the submission result by default.Return Props
Name | Type | Description |
---|---|---|
register | (name: string, RegisterOptions?) => RegisterReturnProps | This method allows you to register an input or select element and apply validation rules to Form. |
formState | Object | This object contains information about the entire form state. |
getFieldId | (fieldName: string) => string | Gets the id of a form field. |
getValues | (payload?: string | string[]) => Object | An optimized helper for reading form values |
handleSubmit | ((data: Object, e?: Event) => Promise<void>, (errors: Object, e?: Event) => void) => Promise<void> | This function will receive the form data if form validation is successful. |
trigger | (name?: string | string[]) => Promise<boolean> | Manually triggers form or input validation. |
clearErrors | (name?: string | string[]) => void | This function can manually clear errors in the form. |
This method allows you to register an input or select element and apply validation rules to Form.
By invoking the register function and supplying an input's name, you will receive the following properties:
Props
Name | Type | Description |
---|---|---|
name | string | Name of the input field |
RegisterOptions | Object | Additional options that can be passed into the register function |
Return Props
Name | Type | Description |
---|---|---|
onChange | ChangeHandler | onChange prop to subscribe the input change event. |
onBlur | ChangeHandler | onBlur prop to subscribe the input blur event. |
id | string | Input's id containing randomly generated string to avoid clashes. Use getFieldId(name) |
isInvalid | boolean | Whether a field is invalid. |
isDisabled | boolean | Whether a field is disabled. |
Name | Type | Description | Example |
---|---|---|---|
required | boolean | A |
|
disabled | boolean | Set disabled to
For schema validation, you can leverage the |
|
max | number | The maximum value to accept for this input. |
|
maxLength | number | The maximum length of the value to accept for this input. |
|
min | number | The minimum value to accept for this input. |
|
minLength | number | The minimum length of the value to accept for this input. |
|
pattern | RegExp | The regex pattern for the input. Note: A RegExp object with the |
|
validate | Function | Object | You can pass a callback function as the argument to validate, or you can pass an object of callback functions to validate all of them. This function will be executed on its own without depending on other validation rules included in the Note: for |
|
1 2import { useForm, Form, Label, Textfield } from "@forge/react"; export default function App() { const { register, handleSubmit, getFieldId, Button } = useForm({ defaultValues: { firstName: '', lastName: '', } }); return ( <Form onSubmit={handleSubmit(console.log)}> <Label labelFor={getFieldId("firstName")}>First Name</Label> <Textfield {...register("firstName", { required: true })}/> <Label labelFor={getFieldId("lastName")}>Last Name</Label> <Textfield {...register("lastName", { minLength: 2 })}/> <Button type="submit" /> </Form> ); }
name
is required and unique. Input name supports dot syntax to allow for nested form fields.1 2register('user.firstname'); // returns {user: {firstname: ''}}
name
can neither start with a number nor use number as key name. Please avoid special characters as well.disabled
input will result in an undefined
form value. If you want to prevent users from updating the input, use isReadOnly
.test.0.data
This object contains information about the entire form state. It helps you to keep on track with the user's interaction with your form application.
Return Props
Name | Type | Description |
---|---|---|
dirtyFields | Object | An object with the user-modified fields. Make sure to provide all inputs' defaultValues via useForm, so the library can compare against the Important: Make sure to provide |
touchedFields | Object | An object containing all the inputs the user has interacted with. |
errors | Object | An object with field errors. |
isSubmitted | boolean | Set to |
isSubmitting | boolean | true if the form is currently being submitted. false otherwise. |
isSubmitSuccessful | boolean | Indicate the form was successfully submitted without any runtime error. |
isValid | boolean | Set to |
submitCount | number | Number of times the form was submitted. |
formState
is wrapped with a Proxy to improve render performance and skip extra logic if specific state is not subscribed to. Therefore make sure to invoke or read it before a render in order to enable the state update.1 2const { isValid } = formState; return <Button disabled={!isValid} type="submit">Submit</Button>;
Retrieves the id
of a registered form field. This should be used to retrieve the correct id
to pass into the Label
component.
Props
Type | Description | Example |
---|---|---|
string | returns the registered form field id. | getFieldId("firstName") |
1 2import { useForm, Form, Button, Textfield, Label } from "@forge/react"; export default function App() { const { getFieldId, register, handleSubmit, // Read the formState before render to subscribe the form state through the Proxy formState: { errors, isSubmitting, submitCount }, } = useForm(); const onSubmit = (data) => console.log(data); return ( <Form onSubmit={handleSubmit(onSubmit)}> <Label labelFor={getFieldId("firstName")}>First Name</Label> <Textfield {...register("firstName")} /> <Button type="submit">Submit</Button> </Form> ); }
id
to prevent conflicts with other components on the page. Use the getFieldId
to retrieve the correct id
of a registered form field.An optimized helper for reading form values, getValues
will not trigger re-renders or subscribe to input changes.
Props
Type | Description | Example |
---|---|---|
undefined | Returns the entire form values. | getValues() |
string | Gets the value at path of the form values. | getValues("person.firstName") |
array | Returns an array of the value at path of the form values. | getValues(["person.firstName", "person.lastName"]) |
The example below shows what to expect when you invoke getValues
method.
1 2import { useForm, Form, Label, Textfield, Button } from "@forge/react" export default function App() { const { register, getValues, getFieldId } = useForm() return ( <Form> <Label labelFor={getFieldId("firstname")}>First name</Label> <Textfield {...register("firstname")} /> <Label labelFor={getFieldId("lastname")}>Last name</Label> <Textfield {...register("lastname")} /> <Button onClick={() => { const values = getValues(); // gets all form values { firstname: '', lastname: ''} const singleValue = getValues("firstname"); // gets single form value { firstname: ''} const multipleValues = getValues(["firstname", "lastname"]); // gets multiple form values { firstname: '', lastname: ''} console.log({ values, singleValue, multipleValues }); }} > Get Values </Button> </Form> ) }
undefined
. If you want to prevent users from updating the input and still retain the field value, you can use readOnly
.defaultValues
from useForm before the initial render.This function will receive the form data if form validation is successful.
Props
Name | Type | Description |
---|---|---|
onSubmit | (data: Object) => Promise<void> | A successful callback. |
onError | (errors: Object) => Promise<void> | An error callback. |
1 2import { useForm, Form, Label, Textfield, Button } from "@forge/react" export default function App() { const { register, handleSubmit } = useForm() const onSubmit = (data) => console.log(data) const onError = (errors) => console.log(errors) return ( <Form onSubmit={handleSubmit(onSubmit, onError)}> <Label labelFor={getFieldId('firstName')}>First Name</Label> <Textfield {...register("firstName")} /> <Label labelFor={getFieldId('lastName')}>First Name</Label> <Textfield {...register("lastName")} /> <Button type="submit">Submit</Button> </Form> ) }
1 2import { useForm, Form, Label, Textfield, Button } from "@forge/react" const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); function App() { const { register, handleSubmit, formState, formState } = useForm(); const { errors, isSubmitting } = formState; const onSubmit = async data => { await sleep(2000); if (data.username === "bill") { console.log(JSON.stringify(data)); } else { console.log("There is an error"); } }; return ( <Form onSubmit={handleSubmit(onSubmit)}> <Label labelFor={getFieldId('username')}>First Name</Label> <Textfield {...register("username")} placeholder="Bill"/> <LoadingButton isLoading={isSubmitting} type="submit">Submit</LoadingButton> </Form> ); }
handleSubmit
.1 2handleSubmit(onSubmit)() // You can pass an async function for asynchronous validation. handleSubmit(async (data) => await fetchAPI(data))
handleSubmit
function will not ignore errors that occurred inside your onSubmit
callback, so we recommend you to try and catch inside async request and handle those errors gracefully for your customers.1 2const onSubmit = async () => { // async request which may result error try { // await fetch() } catch (e) { // handle your error } }; <Form onSubmit={handleSubmit(onSubmit)} />
Manually triggers form or input validation. This method is also useful when you have dependant validation (input validation depends on another input's value).
Props
Name | Type | Description | Example |
---|---|---|---|
name | undefined | Triggers validation on all fields. | trigger() |
string | Triggers validation on a specific field value by name. | trigger("yourDetails.firstName") | |
string[] | Triggers validation on multiple fields by name. | trigger(["yourDetails.lastName"]) |
1 2import { useForm, Form, Label, Textfield, Button } from "@forge/react" export default function App() { const { register, trigger, formState: { errors }, getFieldId, } = useForm() return ( <Form> <Label labelFor={getFieldId("firstName")}>First Name</Label> <Textfield {...register("firstName", { required: true })} /> <Label labelFor={getFieldId("lastName")}>Last Name</Label> <Textfield {...register("lastName", { required: true })} /> <Button type="button" onClick={async () => { const result = await trigger("lastName") }} > Trigger </Button> <Button type="button" onClick={async () => { const result = await trigger(["firstName", "lastName"]) }} > Trigger Multiple </Button> <Button type="button" onClick={() => { trigger() }} > Trigger All </Button> </Form> ) }
string
as payload, when supplied with array
and undefined
to trigger will re-render the entire formState.This function can manually clear errors in the form.
Props
Type | Description | Example |
---|---|---|
undefined | Remove all errors. | clearErrors() |
string | Remove single error. | clearErrors("firstName") |
string[] | Remove multiple errors. | clearErrors(["firstName", "lastName"]) |
Rate this page: