본문으로 건너뛰기

useController

</> useController: (UseControllerProps) => UseControllerReturn

이 사용자 정의 훅은 Controller의 기반으로 동작하며 Controller와 같은 속성 및 메서드를 공유합니다. 재사용 가능한 제어 입력을 만들 때 유용합니다.

매개변수


다음 표는 useController의 인수에 관한 정보를 제공합니다.

이름타입필수설명
nameFieldPath입력의 고유한 이름입니다. 반응형으로 동작하므로 이 속성이 변경되면 controller가 다시 구독하며, 필드 이름을 동적으로 전환할 수 있습니다.
controlControlcontrol 객체는 useForm을 호출하면 제공됩니다. FormProvider를 사용할 때는 선택 사항입니다.
rulesObjectregister와 같은 형식의 검증 규칙입니다. required, min, max, minLength, maxLength, pattern, validate를 포함합니다.

rules={{ required: true }}
shouldUnregisterboolean = false입력이 언마운트되면 등록이 해제되고 defaultValues도 제거됩니다. 참고: useFieldArray와 함께 사용할 때는 입력 언마운트/리마운트 및 순서 변경 후 unregister 함수가 호출되므로 이 속성을 사용하지 않는 것이 좋습니다.
disabledboolean = falsev7.46.0부터 disabled 속성이 field 속성에서 반환됩니다. 제어 입력이 비활성화되고 해당 값은 제출 데이터에서 제외됩니다.
defaultValueunknown중요: undefineddefaultValue 또는 defaultValuesuseForm에서 적용할 수 없습니다.
  • 필드 수준의 defaultValueuseFormdefaultValues 중 하나를 설정해야 합니다. undefined는 유효한 값이 아닙니다. defaultValuesuseForm에서 사용했다면 이 속성은 생략합니다.
  • 폼에서 기본값과 함께 reset을 호출할 예정이라면 useFormdefaultValues를 제공해야 합니다.
  • 첫 렌더링에서 field.valueundefined이면 입력은 비제어 상태로 시작하며 이후 제어 상태로 바뀔 때 React가 경고합니다. 이를 방지하려면 항상 defaultValue/defaultValues를 설정합니다.
exactboolean = truev7.68.0부터 입력 이름 구독의 정확한 일치를 활성화하며 기본값은 true입니다. v7.81.0부터 exact: true이면 상위 경로 중 하나가 설정될 때도 필드가 갱신됩니다(예: 이름이 "users.0.name"인 필드에는 setValue("users.0", { name: "Jane" })가 반영됨). 하지만 값의 하위 경로가 변경될 때는 갱신되지 않습니다(예: setValue("users.0.name", "Jane")은 이름이 "users.0"인 필드를 갱신하지 않음). 중첩된 갱신도 받으려면 exact: false를 전달합니다. 참고: useWatchuseFormState는 모두 exact의 기본값이 false이므로 이 동작과 다릅니다.

반환값


다음 표는 useController가 반환하는 속성에 관한 정보를 제공합니다.

객체 이름이름타입설명
fieldonChange(value: any) => void입력 값을 라이브러리에 전달하는 함수입니다. 입력의 onChange 속성에 할당해야 하며 값은 undefined가 아니어야 합니다. 이 속성은 formState를 갱신하므로 setValue나 필드 갱신과 관련된 다른 API를 직접 호출하지 않는 것이 좋습니다.
fieldonBlur() => void입력의 onBlur 이벤트를 라이브러리에 전달하는 함수입니다. 입력의 onBlur 속성에 할당해야 합니다.
fieldvalueunknown제어 컴포넌트의 현재 값입니다.
fielddisabledboolean입력의 비활성화 상태입니다.
fieldnamestring등록 중인 입력의 이름입니다.
fieldrefReact.RefReact Hook Form을 입력에 연결하는 ref입니다. 오류가 있는 입력에 React Hook Form이 포커스를 설정할 수 있도록 컴포넌트의 입력 ref에 ref를 할당합니다.
fieldStateinvalidboolean현재 입력의 invalid 상태입니다.
fieldStateisTouchedboolean현재 제어 입력의 touched 상태입니다.
fieldStateisDirtyboolean현재 제어 입력의 dirty 상태입니다.
fieldStateerrorobjectv7.0.0부터 이 입력의 오류입니다.
formStateisDirtyboolean사용자가 입력 중 하나라도 수정하면 true로 설정됩니다. 중요: 모든 입력의 defaultValuesuseForm에 제공하여 React Hook Form이 폼의 dirty 상태를 비교할 단일 기준을 갖게 해야 합니다.
formStatedirtyFieldsobject사용자가 수정한 필드를 담은 객체입니다. 라이브러리가 defaultValues와 비교할 수 있도록 useForm에 모든 입력의 defaultValues를 제공해야 합니다.
formStatetouchedFieldsobject사용자가 상호작용한 모든 입력을 담은 객체입니다.
formStatedefaultValuesobjectv7.37.0부터 useFormdefaultValues에 설정했거나 defaultValuesreset API로 갱신한 값입니다.
formStateisSubmittedboolean폼이 제출되면 true로 설정되고, true 상태는 reset 메서드를 호출할 때까지 유지됩니다.
formStateisSubmitSuccessfulboolean런타임 오류 없이 폼이 성공적으로 제출되었음을 나타냅니다.
formStateisSubmittingboolean현재 폼을 제출 중이면 true, 그렇지 않으면 false입니다.
formStateisLoadingbooleanv7.41.0부터 현재 폼이 비동기 기본값을 불러오는 중이면 true입니다. 중요: 이 속성은 비동기 defaultValues에만 적용됩니다.
formStatesubmitCountnumber폼이 제출된 횟수입니다.
formStateisValidboolean폼에 오류가 없으면 true로 설정됩니다. setError는 즉시 isValidfalse로 강제합니다. 이 값 자체는 검증에서 파생되지 않으며, 다음 검증이 실행될 때(예: 다음 onChange, 제출 또는 trigger() 호출) 덮어쓰입니다.
formStateisValidatingboolean검증 중에는 true로 설정됩니다.
formStatevalidatingFieldsobjectv7.51.0부터 비동기 검증이 진행 중인 필드를 담습니다.
formStateerrorsobject필드 오류를 담은 객체입니다. 오류 메시지를 쉽게 가져올 수 있는 ErrorMessage 컴포넌트도 있습니다.
formStatedisabledbooleanv7.48.0부터 true로 설정되는 경우는 disabled 속성을 useForm에 전달해 폼을 비활성화했을 때입니다.
formStateisReadybooleanv7.56.0부터 formState 구독 설정이 준비되면 true로 설정됩니다.

예제


import { TextField } from "@mui/material"
import { useController, useForm } from "react-hook-form"

function Input({ control, name }) {
const {
field,
fieldState: { invalid, isTouched, isDirty },
formState: { touchedFields, dirtyFields },
} = useController({
name,
control,
rules: { required: true },
})

return (
<TextField
onChange={field.onChange} // send the value to hook form
onBlur={field.onBlur} // notify when the input is touched or blurred
value={field.value} // input value
name={field.name} // send the input name
inputRef={field.ref} // send input ref, so we can focus on the input when an error appears
/>
)
}


  • MUI, AntD, Chakra UI 같은 외부 제어 컴포넌트를 사용할 때는 각 속성의 역할을 이해해야 합니다. 이 훅은 입력을 관찰하고, 상태를 보고하며, 값을 설정합니다.

    • onChange: 데이터를 React Hook Form으로 다시 전달합니다.
    • onBlur: 입력과 상호작용했음을 보고합니다(포커스 및 blur).
    • value: 입력의 초기값과 갱신된 값을 설정합니다.
    • ref: 오류가 있는 입력에 포커스를 설정할 수 있게 합니다. 대상 컴포넌트가 ref를 전달하거나(React.forwardRef) MUI의 inputRef처럼 동등한 기능을 노출할 때만 작동합니다. ref를 전혀 받지 않는다면 spread 대상에서 ref를 제외하고 포커스를 직접 처리합니다.
    • name: 입력에 고유한 이름을 부여합니다.

    자체 상태를 유지하면서 useController와 함께 사용해도 됩니다.

    const { field } = useController({ name: 'test' });
    const [value, setValue] = useState(field.value);

    onChange={(event) => {
    field.onChange(parseInt(event.target.value)) // data sent back to hook form
    setValue(event.target.value) // UI state
    }}
  • 입력을 다시 register하지 않습니다. 이 사용자 정의 훅이 등록 과정을 처리하도록 설계되어 있습니다.

    const { field } = useController({ name: 'test' })

    <input {...field} /> // ✅
    <input {...field} {...register('test')} /> // ❌ double up the registration
  • 컴포넌트마다 useController를 한 번만 호출하는 것이 좋습니다. 호출할 때마다 별도의 구독이 생성되므로 한 컴포넌트에서 여러 번 호출하면 불필요한 리렌더링이 발생할 수 있습니다. 같은 컴포넌트에 제어 필드가 둘 이상 필요하다면 구조 분해한 각 field의 이름을 바꿔 이름 충돌을 피하거나 Controller 사용을 고려합니다.

    const { field: input } = useController({ name: 'test' })
    const { field: checkbox } = useController({ name: 'test1' })

    <input {...input} />
    <input {...checkbox} />