Skip to content

useWatch

입력 변경 사항을 구독하기 위한 React Hook

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

watch API와 비슷하게 동작하지만, 이 훅은 커스텀 훅 수준에서 리렌더링을 분리하여 애플리케이션의 성능을 더욱 향상시킬 수 있습니다.

Props


이름타입설명
namestring | string[] | undefined필드의 이름.
controlObjectuseForm에서 제공하는 control 객체. FormProvider를 사용 중이라면 선택 사항.
defaultValueunknown초기 렌더링 전에 useWatch가 반환할 기본값.

참고: 첫 렌더링 시 defaultValue가 제공되면 항상 이 값을 반환.
disabledboolean = false구독을 비활성화할지 여부.
exactboolean = false이 프로퍼티는 입력 이름 구독에 정확한 일치를 활성화.

Return


예제반환값
useWatch({ name: 'inputName' })unknown
useWatch({ name: ['inputName1'] })unknown[]
useWatch(){[key:string]: unknown}
규칙
  • useWatch의 초기 반환값은 항상 useFormdefaultValue 또는 defaultValues 안에 있는 값을 반환합니다.

  • useWatchwatch의 유일한 차이점은 루트(useForm) 레벨 또는 커스텀 훅 레벨 업데이트에서 발생합니다.

  • useWatch의 실행 순서가 중요합니다. 즉, 구독이 설정되기 전에 폼 값을 업데이트하면 업데이트된 값이 무시됩니다.

    setValue("test", "data")
    useWatch({ name: "test" }) // ❌ 값 업데이트 후 구독이 발생하여 업데이트를 받지 못함
    useWatch({ name: "example" }) // ✅ 입력 값 업데이트를 받고 리렌더링을 트리거함
    setValue("example", "data")

    위 문제는 아래와 같은 간단한 커스텀 훅으로 해결할 수 있습니다:

    const useFormValues = () => {
    const { getValues } = useFormContext()
    return {
    ...useWatch(), // 폼 값 업데이트 구독
    ...getValues(), // 항상 최신 폼 값과 병합
    }
    }
  • 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", // 이름을 제공하지 않으면 전체 폼을 감시하거나, ['firstName', 'lastName']로 둘 다 감시
defaultValue: "default", // 렌더링 전 기본값
})
return <p>Watch: {firstName}</p> // firstName이 변경될 때만 커스텀 훅 레벨에서 리렌더링
}
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)
// 필드 배열과 함께 결과를 계산하기 위한 독립된 리렌더링
console.log(results)
setValue("total", output)
return <p>{output}</p>
}

여러분의 지원에 감사드립니다

React Hook Form이 프로젝트에서 유용하다면, GitHub에서 스타를 눌러 지원해 주세요.