Skip to content

useWatch

用于订阅输入更改的 React Hook

</> 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


名称类型描述
namestring | string[] | undefined字段名称。
controlObjectcontrol 对象由 useForm 提供。如果你使用 FormProvider,则它是可选的。
defaultValueunknownuseWatch 在初始渲染之前返回的默认值。

注意:第一次渲染在提供时将始终返回 defaultValue
disabledboolean = false禁用订阅的选项。
exactboolean = false此属性将为输入名称订阅启用精确匹配。

返回

¥Return


示例返回
useWatch({ name: 'inputName' })unknown
useWatch({ name: ['inputName1'] })unknown[]
useWatch(){[key:string]: unknown}
RULES
  • useWatch 的初始返回值将始终返回 useFormdefaultValuedefaultValues 内部的内容。

    ¥The initial return value from useWatch will always return what's inside of defaultValue or defaultValues from useForm.

  • useWatchwatch 之间的唯一区别在于根 (useForm) 级别或自定义钩子级别更新。

    ¥The only difference between useWatch and watch 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 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 的结果针对渲染阶段而不是 useEffect 的 deps 进行了优化,为了检测值更新,你可能需要使用外部自定义钩子进行值比较。

    ¥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:


表单

¥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>
)
}
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
for (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 Array
console.log(results)
setValue("total", output)
return <p>{output}</p>
}
React Hook Form 中文网 - 粤ICP备13048890号