跳至内容

useWatch

React Hook 用于订阅输入更改

</> useWatch: ({ control?: Control, name?: string, defaultValue?: unknown, disabled?: boolean }) => object

行为类似于 watch API,但是,这将隔离自定义挂钩级别的重新渲染,并可能为您的应用程序带来更好的性能。

Props


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

注意: 首次渲染始终返回 defaultValue(如果提供)。
disabledboolean = false禁用订阅的选项。
exactboolean = false此道具将启用对输入名称订阅的精确匹配。

返回值


示例返回值
useWatch({ name: 'inputName' })未知
useWatch({ name: ['inputName1'] })unknown[]
useWatch(){[key:string]: unknown}
规则
  • useWatch 的初始返回值始终返回 defaultValueuseForm 中的 defaultValues 内的内容。

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

  • useWatch 的执行顺序很重要,这意味着如果您在订阅就位之前更新表单值,则更新的值将被忽略。

    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")

    您可以使用以下简单的自定义挂钩克服上述问题

    const useFormValues = () => {
    const { getValues } = useFormContext()
    return {
    ...useWatch(), // subscribe to form value updates
    ...getValues(), // always merge with latest form values
    }
    }
  • useWatch 的结果针对渲染阶段而不是 useEffect 的依赖项进行了优化,要检测值更新,您可能需要使用外部自定义挂钩进行值比较。

示例


表单

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>
)
}

高级字段数组

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 对您的项目有用,请考虑为它加星并支持它。