watch: (names?: string | string[] | (data, options) => void) => unknown
This will watch specified inputs and return their values. It is useful for determining what to render.
Rules
When
defaultValueis not defined, the first render ofwatchwill returnundefinedbecause it is called beforeregister, but you can set thedefaultValueas the second argument or providedefaultValuesviauseFormto avoid this behaviour.If
defaultValueswas initialised inuseFormas an argument, then the first render will return what's provided indefaultValues.After the first render, default values will be shallowly merged with the current form values from the inputs.
This API will trigger re-render at the root of your app or form, consider using a callback or the useWatch api if you are experiencing performance issues.
watchresult is optimised for render phase instead ofuseEffect's deps, to detect value update you may want to use an external custom hook for value comparison.
Return
| Type | Description | Example | Return |
|---|---|---|---|
string | Watch input value by name (similar to lodash get function) | watch('inputName')watch('inputName', 'value') | any |
string[] | Watch multiple inputs | watch(['inputName1'])watch(['field1'], { field1: '1' }) | unknown[] |
undefined | Watch all inputs | watch()watch(undefined, { field: '1' }) | {[key:string]: any} |
(data: unknown, { name: string, type: string }) => void | Watch all inputs and invoke a callback | watch((data, { name, type }) => console.log(data, name, type)) | { unsubscribe: () => void } |
import React from "react"; import { useForm } from "react-hook-form"; function App() { const { register, watch, formState: { errors }, handleSubmit } = useForm(); const watchShowAge = watch("showAge", false); // you can supply default value as second argument const watchAllFields = watch(); // when pass nothing as argument, you are watching everything const watchFields = watch(["showAge", "number"]); // you can also target specific fields by their names // Callback version of watch. It's your responsibility to unsubscribe when done. React.useEffect(() => { const subscription = watch((value, { name, type }) => console.log(value, name, type)); return () => subscription.unsubscribe(); }, [watch]); const onSubmit = data => console.log(data); return ( <> <form onSubmit={handleSubmit(onSubmit)}> <input type="checkbox" {...register("showAge")} /> {/* based on yes selection to display Age Input*/} {watchShowAge && <input type="number" {...register("age", { min: 50 })} />} <input type="submit" /> </form> </> ); }import React from "react"; import { useForm } from "react-hook-form"; interface IFormInputs { name: string showAge: boolean age: number } function App() { const { register, watch, formState: { errors }, handleSubmit } = useForm<IFormInputs>(); const watchShowAge = watch("showAge", false); // you can supply default value as second argument const watchAllFields = watch(); // when pass nothing as argument, you are watching everything const watchFields = watch(["showAge", "age"]); // you can also target specific fields by their names // Callback version of watch. It's your responsibility to unsubscribe when done. React.useEffect(() => { const subscription = watch((value, { name, type }) => console.log(value, name, type)); return () => subscription.unsubscribe(); }, [watch]); const onSubmit = (data: IFormInputs) => console.log(data); return ( <> <form onSubmit={handleSubmit(onSubmit)}> <input {...register("name", { required: true, maxLength: 50 })} /> <input type="checkbox" {...register("showAge")} /> {/* based on yes selection to display Age Input*/} {watchShowAge && ( <input type="number" {...register("age", { min: 50 })} /> )} <input type="submit" /> </form> </> ); }