</> useWatch:
({ control?: Control, name?: string, defaultValue?: unknown, disabled?: boolean }) => object
其行为与 watch
API 类似,但是,这将隔离自定义钩子级别的重新渲染,并可能为你的应用带来更好的性能。
¥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 | string | string[] | undefined | 字段名称。 |
control | Object | control 对象由 useForm 提供。如果你使用 FormProvider ,则它是可选的。 |
defaultValue | unknown | useWatch 在初始渲染之前返回的默认值。注意:第一次渲染在提供时将始终返回 defaultValue 。 |
disabled | boolean = false | 禁用订阅的选项。 |
exact | boolean = false | 此属性将为输入名称订阅启用精确匹配。 |
返回
¥Return
示例 | 返回 |
---|---|
useWatch({ name: 'inputName' }) | unknown |
useWatch({ name: ['inputName1'] }) | unknown[] |
useWatch() | {[key:string]: unknown} |
-
useWatch
的初始返回值将始终返回useForm
中defaultValue
或defaultValues
内部的内容。¥The initial return value from
useWatch
will always return what's inside ofdefaultValue
ordefaultValues
fromuseForm
. -
useWatch
和watch
之间的唯一区别在于根 (useForm
) 级别或自定义钩子级别更新。¥The only difference between
useWatch
andwatch
is at the root (useForm
) level or the custom hook level update. -
useWatch
的执行顺序很重要,这意味着如果你在订阅到位之前更新表单值,则更新的值将被忽略。¥
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
的结果针对渲染阶段而不是useEffect
的 deps 进行了优化,为了检测值更新,你可能需要使用外部自定义钩子进行值比较。¥
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:
表单
¥Form
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>)}
高级场数组
¥Advanced Field Array
import React from "react"import { useWatch } from "react-hook-form"function totalCal(results) {let totalValue = 0for (const key in results) {for (const value in results[key]) {if (typeof results[key][value] === "string") {const output = parseInt(results[key][value], 10)totalValue = totalValue + (Number.isNaN(output) ? 0 : output)} else {totalValue = totalValue + totalCal(results[key][value], totalValue)}}}return totalValue}export const Calc = ({ control, setValue }) => {const results = useWatch({ control, name: "test" })const output = totalCal(results)// isolated re-render to calc the result with Field Arrayconsole.log(results)setValue("total", output)return <p>{output}</p>}