</> useWatch:
({ control?: Control, name?: string, defaultValue?: unknown, disabled?: boolean }) => object
watch
API와 유사하게 동작하지만, 이 훅은 리렌더링을 커스텀 훅 레벨에서 격리하여 애플리케이션의 성능을 향상시킬 수 있습니다.
Props
Name | Type | Description |
---|---|---|
name | string | string[] | undefined | 필드의 이름. |
control | Object | useForm 이 제공하는 control 객체. FormProvider 를 사용하는 경우, 이 props는 선택 사항입니다. |
defaultValue | unknown | 초기 렌더링 전에 useWatch 가 반환할 기본 값.참고: defaultValue 가 제공되면 첫 번째 렌더링 시에는 항상 defaultValue 을 반환합니다. |
disabled | boolean = false | 구독을 비활성화하는 옵션. |
exact | boolean = false | 이 prop은 입력 필드의 이름 구독에 대한 정확한 일치가 가능하도록 합니다. |
Return
Example | Return |
---|---|
useWatch({ name: 'inputName' }) | unknown |
useWatch({ name: ['inputName1'] }) | unknown[] |
useWatch() | {[key:string]: unknown} |
RULES
-
useWatch
의 초기 반환 값은 항상defaultValue
또는useForm
의defaultValues
에 있는 값을 반환합니다. -
useWatch
와watch
의 유일한 차이점은 루트(useForm
) 레벨 또는 커스텀 훅 레벨에서의 업데이트에 있습니다. -
useWatch
의 실행 순서는 중요합니다. 즉, 구독이 설정되기 전에 폼 값을 업데이트 하면, 해당 변경 사항이 무시됩니다.setValue("test", "data")useWatch({ name: "test" }) // ❌ 값이 업데이트 된 후 구독이 발생하고, 변경 사항이 반영되지 않음useWatch({ name: "example" }) // ✅ 입력 값 변경이 반영되고, 리렌더링이 트리거됨setValue("example", "data")위 문제는 다음과 같은 간단한 커스텀 훅을 사용하여 해결할 수 있습니다:
const useFormValues = () => {const { getValues } = useFormContext()return {...useWatch(), // 폼 값 업데이트를 구독합니다....getValues(), // 항상 최신 폼 값과 병합합니다.}} -
useWatch
의 결과는useEffect
의 의존성 배열 대신 렌더 단계(render phase)에 최적화되어 있습니다. 값의 변화를 감지하려면 값 비교를 위한 외부 커스텀 훅을 사용하는 것이 좋습니다.
Examples:
폼
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", // 이름을 지정하지 않으면 전체 폼을 감지하며,['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 { 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)// 필드 배열로 결과를 계산하기 위해 독립적인 리렌더링console.log(results)setValue("total", output)return <p>{output}</p>}
지원해 주셔서 감사합니다
프로젝트에서 React Hook Form이 유용하다고 생각하신다면, 스타를 눌러 지원해 주시길 부탁드립니다.