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 FormContext. |
defaultValue | unknown | default value for Note: the first render will always return |
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('inputName') | unknown |
useWatch(['inputName1']) | unknown[] |
useWatch() | {[key:string]: unknown} |
Rules
The initial return value from
useWatch
will always return what's inside ofdefaultValue
ordefaultValues
fromuseForm
.The only difference between
useWatch
andwatch
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 received useWatch({ name: 'example' }); // ✅ input value update will be received and trigger re-render setValue('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 ofuseEffect
'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"; function Child({ control }) { const firstName = useWatch({ control, name: "firstName", }); return <p>Watch: {firstName}</p>; } function App() { const { register, control } = useForm({ firstName: "test" }); return ( <form> <input {...register("firstName")} /> <Child control={control} /> </form> ); }
import React from "react"; import { useForm, useWatch } from "react-hook-form"; interface FormInputs { firstName: string; lastName: 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 both defaultValue: "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> ); }
Thank you for your support
If you find React Hook Form to be useful in your project, please consider to star and support it.