</>
useWatch:
({ control?: Control, name?: string, defaultValue?: unknown, disabled?: boolean }) => object
Behaves similarly to the
watch
API, however, this will isolate re-rendering at the custom hook level and potentially result in better performance for your application.
Props
Name | Type | Description |
---|---|---|
name
|
string | string[] | undefined | Name of the field. |
control
|
Object |
control
object provided by
useForm
. It's optional if you are using
FormProvider
.
|
defaultValue
|
unknown |
default value for
useWatch
to return before the initial render.
Note: the first render will always return
defaultValue
when it's supplied.
|
disabled
|
boolean = false | Option to disable the subscription. |
exact
|
boolean = false | This prop will enable an exact match for input name subscriptions. |
Return
Example | Return |
---|---|
useWatch({ name: 'inputName' })
|
unknown |
useWatch({ name: ['inputName1'] })
|
unknown[] |
useWatch()
|
{[key:string]: unknown}
|
The initial return value from
useWatch
will always return what's inside of
defaultValue
or
defaultValues
from
useForm
.
The only difference between
useWatch
and
watch
is at the root (
useForm
) level or the custom hook level update.
useWatch
's execution order matters, which means if you update a form value before the subscription is in place, then the value updated will be ignored.
setValue("test", "data")useWatch({ name: "test" }) // ❌ subscription is happened after value update, no update receiveduseWatch({ name: "example" }) // ✅ input value update will be received and trigger re-rendersetValue("example", "data")
You can overcome the above issue with a simple custom hook as below:
const useFormValues = () => {const { getValues } = useFormContext()return {...useWatch(), // subscribe to form value updates...getValues(), // always merge with latest form values}}
useWatch
's result is optimised for render phase instead of
useEffect
's deps, to detect value updates you may want to use an external custom hook for value comparison.
Examples:
import React from "react"import { useForm, useWatch } from "react-hook-form"interface FormInputs {firstName: stringlastName: string}function FirstNameWatched({ control }: { control: Control<FormInputs> }) {const firstName = useWatch({control,name: "firstName", // without supply name will watch the entire form, or ['firstName', 'lastName'] to watch bothdefaultValue: "default", // default value before the render})return <p>Watch: {firstName}</p> // only re-render at the custom hook level, when firstName changes}function App () {const { register, control, handleSubmit } = useForm<FormInputs>()const onSubmit = (data: FormInputs) => {console.log(data)}return (<form onSubmit={handleSubmit(onSubmit)}><label>First Name:</label><input {...register("firstName")} /><input {...register("lastName")} /><input type="submit" /><FirstNameWatched control={control} /></form>)}
import React from "react"import { useForm, useWatch } from "react-hook-form"function Child({ control }) {const firstName = useWatch({control,name: "firstName",})return <p>Watch: {firstName}</p>}function App() {const { register, control } = useForm({defaultValues: {firstName: "test",},})return (<form><input {...register("firstName")} /><Child control={control} /></form>)}
Advanced Field Array
import React from "react"import { useWatch } from "react-hook-form"function totalCal(results) {let totalValue = 0