Skip to content

Controller

제어 입력 필드를 위한 래퍼(Wrapper) 컴포넌트

</> Controller: Component

React Hook Form은 비제어 컴포넌트와 기본 입력 요소를 지향하지만, React-Select, AntD, MUI와 같은 외부 제어 컴포넌트와 React Hook Form을 함께 사용하는 상황은 피하기 어렵습니다. 이 래퍼 컴포넌트는 이러한 작업을 더욱 쉽게 만들어줍니다.

Props


다음 표는 Controller의 인자에 대한 정보를 담고 있습니다.

NameTypeRequiredDescription
nameFieldPath입력 필드에 대한 고유한 이름.
controlControlcontrol 객체는 useForm을 호출하여 얻을 수 있습니다. FormProvider를 사용할 때는 선택 사항입니다.
renderFunction이는 render prop입니다. 리액트 요소를 반환하는 함수로, 컴포넌트에 이벤트와 값을 연결할 수 있는 기능을 제공합니다. 이를 통해 비표준 prop 이름을 사용하는 외부 제어 컴포넌트와의 통합이 간편해집니다. 자식 컴포넌트에 onChange, onBlur, name, ref, value 를 제공하며, 특정 입력 상태를 포함하는 fieldState 객체도 제공합니다.
defaultValueunknown중요: defaultValue 또는 useFormdefaultValues에서 undefined를 사용할 수 없습니다.
  • 필드 레벨에서 defaultValueuseFormdefaultValues를 설정해야 합니다. undefined는 유효한 값이 아닙니다.
  • 폼에서 기본값으로 reset을 호출하여 폼을 초기화할 경우,useFormdefaultValues를 제공해야 합니다.
  • onChangeundefined를 전달하는 것은 유효하지 않습니다. 대신 null이나 빈 문자열을 기본값이나 초기화된 값으로 사용해야 합니다.
rulesObjectregister options 형식의 유효성 검사 규칙은 다음을 포함합니다:

required, min, max, minLength, maxLength, pattern, validate
shouldUnregisterboolean = false`입력 값은 언마운트 후에 등록이 해제(unregistered)되며, 기본값도 제거됩니다.

참고: 이 prop은 useFieldArray와 함께 사용하지 않아야 합니다. 입력 값이 언마운트/리마운트 및 재정렬된 후에 unregister함수가 호출되기 때문입니다.
disabledboolean = false`disabled prop은 field prop에서 반환됩니다. 제어 입력 필드는 비활성화되며, 그 값은 제출 데이터에서 제외됩니다.

Return


다음 표는 Controller가 생성하는 프로퍼티에 대한 정보를 담고 있습니다.

Object NameNameTypeDescription
fieldonChange(value: any) => void입력 값을 라이브러리에 전달하는 함수.

이 함수는 입력 필드의 onChange prop에 할당해야 하며, 값은 undefined가 될 수 없습니다.
이 prop은 formState를 업데이트하므로, setValue나 필드 업데이트와 관련된 다른 API를 직접 호출하는 것은 피해야 합니다.
fieldonBlur() => void입력의 onBlur 이벤트를 라이브러리로 전달하는 함수. 이 함수는 입력 필드의 onBlur prop에 할당되어야 합니다.
fieldvalueunknown제어 컴포넌트의 현재 값.
fielddisabledboolean입력 필드의 비활성화 상태.
fieldnamestring등록된(registered) 입력 필드의 이름.
fieldrefReact.ref입력 필드를 hook form에 연결하는데 사용하는 ref. hook form이 에러가 발생한 입력 필드에 포커스를 맞출 수 있도록 컴포넌트 입력 필드 ref에 ref를 할당하세요.
fieldStateinvalidboolean현재 입력 필드의 유효하지 않은 상태.
fieldStateisTouchedboolean현재 제어 입력 필드의 터치 상태.
fieldStateisDirtyboolean현재 제어 입력 필드의 변경 상태.
fieldStateerrorobject해당 특정 입력 필드의 에러.
formStateisDirtyboolean사용자가 입력을 수정하면 true로 설정합니다.
  1. 중요: 모든 입력 필드의 기본값을 useForm에 제공하여 hook form이 폼이 변경되었는지 여부를 비교할 때 사용할 단일 기준을 가질 수 있도록 하세요.
  2. 파일 타입 입력 필드는 파일 선택, 취소 기능과 FileList 객체로 인해 앱 수준에서 관리가 되어야 합니다.
formStatedirtyFieldsobject사용자가 수정한 필드를 담고 있는 객체. 라이브러리가 defaultValues와 비교할 수 있도록, 모든 입력 필드의 기본값을 useForm을 통해 제공하세요.
  1. 중요: 각 필드의 변경 여부를 비교할 수 있도록, useForm에 defaultValues를 제공하여 hook form이 단일 기준을 가지도록 하세요.
  2. 변경된 필드는 isDirty formState로 나타나지 않습니다. 변경된 필드가 전체 폼이 아닌 필드 수준에서의 dirty 상태로 표시되기 때문입니다. 전체 폼 상태를 확인하려면 isDirty를 사용하세요.
formStatetouchedFieldsobject사용자가 상호작용한 모든 입력 요소를 포함하는 객체.
formStatedefaultValuesobjectuseForm의 기본값에 설정된 값 또는 reset API를 통해 업데이트된 기본값.
formStateisSubmittedboolean폼이 제출된 후 true로 설정합니다. reset 메서드가 호출될 때까지 true로 유지됩니다.
formStateisSubmitSuccessfulboolean런타임 에러 없이 폼이 성공적으로 제출되었음을 나타냅니다.
formStateisSubmittingboolean현재 폼이 제출 중이면 true, 그렇지 않으면 false로 설정합니다.
formStateisLoadingboolean폼이 현재 비동기 기본값을 로딩 중이면 true로 설정합니다.
중요: 이 prop은 비동기 defaultValues에만 적용됩니다.
formStatesubmitCountnumber제출된 횟수.
formStateisValidboolean에러가 없는 경우 true로 설정합니다.

setError는 formState의 isValid 값에 영향을 주지 않으며, isValid는 항상 전체 폼 유효성 검사 결과를 통해 계산됩니다.
formStateisValidatingboolean유효성 검사를 하고 있는 동안 true로 설정합니다.
formStateerrorsobject필드 에러를 담고 있는 객체. 에러 메세지를 쉽게 가져올 수 있도록 도와주는 ErrorMessage 컴포넌트도 제공됩니다.

Examples:


Web

import ReactDatePicker from "react-datepicker"
import { TextField } from "@material-ui/core"
import { useForm, Controller } from "react-hook-form"
type FormValues = {
ReactDatepicker: string
}
function App() {
const { handleSubmit, control } = useForm<FormValues>()
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<Controller
control={control}
name="ReactDatepicker"
render={({ field: { onChange, onBlur, value, ref } }) => (
<ReactDatePicker
onChange={onChange} // hook form에 값 전달
onBlur={onBlur} // 입력이 터치/블러될 때 알림
selected={value}
/>
)}
/>
<input type="submit" />
</form>
)
}
import React from "react"
import ReactDatePicker from "react-datepicker"
import { TextField } from "@material-ui/core"
import { useForm, Controller } from "react-hook-form"
function App() {
const { handleSubmit, control } = useForm()
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<Controller
control={control}
name="ReactDatepicker"
render={({ field: { onChange, onBlur, value, ref } }) => (
<ReactDatePicker
onChange={onChange}
onBlur={onBlur}
selected={value}
/>
)}
/>
<input type="submit" />
</form>
)
}

React Native

import { Text, View, TextInput, Button, Alert } from "react-native"
import { useForm, Controller } from "react-hook-form"
export default function App() {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: {
firstName: "",
lastName: "",
},
})
const onSubmit = (data) => console.log(data)
return (
<View>
<Controller
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
placeholder="First name"
onBlur={onBlur}
onChangeText={onChange}
value={value}
/>
)}
name="firstName"
/>
{errors.firstName && <Text>This is required.</Text>}
<Controller
control={control}
rules={{
maxLength: 100,
}}
render={({ field: { onChange, onBlur, value } }) => (
<TextInput
placeholder="Last name"
onBlur={onBlur}
onChangeText={onChange}
value={value}
/>
)}
name="lastName"
/>
<Button title="Submit" onPress={handleSubmit(onSubmit)} />
</View>
)
}

Video


다음 비디오는 Controller의 내부와 그것이 어떻게 구성되어 있는지를 보여줍니다.

TIP
  • MUI, AntD, Chakra UI와 같은 외부 제어 컴포넌트를 사용할 때 각 prop의 역할을 이해하는 것이 중요합니다. Controller는 값을 알리고 설정함으로써 입력 필드의 "스파이" 역할을 합니다.

    • onChange: 다시 hook form으로 데이터를 전달.
    • onBlur: 입력이 유저와 상호작용(focus 및 blur)이 있었음을 보고.
    • value: 입력 필드의 초기 값과 변경된 값을 설정.
    • ref: 에러가 있는 입력 필드에 포커스가 이동할 수 있도록 허용.
    • name: 입력 필드에 고유한 이름을 부여. 다음 코드샌드박스는 사용 예시를 보여줍니다:
    • MUI와 다른 컴포넌트
    • Chakra UI 컴포넌트
  • 입력을 다시 등록(register)하지 마세요. 이 컴포넌트는 입력 필드의 등록(registration) 과정을 처리하도록 설계되어 있습니다.

    <Controller
    name="test"
    render={({ field }) => {
    // return <input {...field} {...register('test')} />; ❌ double up the registration
    return <input {...field} /> // ✅
    }}
    />
  • onChange 이벤트에서 값을 변환하여 hook form에 전달될 값을 원하는 형태로 변경할 수 있습니다.

    <Controller
    name="test"
    render={({ field }) => {
    // sending integer instead of string.
    return (
    <input
    {...field}
    onChange={(e) => field.onChange(parseInt(e.target.value))}
    />
    )
    }}
    />

지원해 주셔서 감사합니다

프로젝트에서 React Hook Form이 유용하다고 생각하신다면, 스타를 눌러 지원해 주시길 부탁드립니다.