</> Controller
: Component
React Hook Form은 비제어 컴포넌트와 기본 입력 요소를 지향하지만, React-Select, AntD, MUI와 같은 외부 제어 컴포넌트와 React Hook Form을 함께 사용하는 상황은 피하기 어렵습니다. 이 래퍼 컴포넌트는 이러한 작업을 더욱 쉽게 만들어줍니다.
Props
다음 표는 Controller
의 인자에 대한 정보를 담고 있습니다.
Name | Type | Required | Description |
---|---|---|---|
name | FieldPath | ✓ | 입력 필드에 대한 고유한 이름. |
control | Control | control 객체는 useForm 을 호출하여 얻을 수 있습니다. FormProvider 를 사용할 때는 선택 사항입니다. | |
render | Function | 이는 render prop입니다. 리액트 요소를 반환하는 함수로, 컴포넌트에 이벤트와 값을 연결할 수 있는 기능을 제공합니다. 이를 통해 비표준 prop 이름을 사용하는 외부 제어 컴포넌트와의 통합이 간편해집니다. 자식 컴포넌트에 onChange , onBlur , name , ref , value 를 제공하며, 특정 입력 상태를 포함하는 fieldState 객체도 제공합니다. | |
defaultValue | unknown | 중요: defaultValue 또는 useForm 의 defaultValues 에서 undefined 를 사용할 수 없습니다.
| |
rules | Object | register options 형식의 유효성 검사 규칙은 다음을 포함합니다:required, min, max, minLength, maxLength, pattern, validate | |
shouldUnregister | boolean = false` | 입력 값은 언마운트 후에 등록이 해제(unregistered)되며, 기본값도 제거됩니다. 참고: 이 prop은 useFieldArray 와 함께 사용하지 않아야 합니다. 입력 값이 언마운트/리마운트 및 재정렬된 후에 unregister 함수가 호출되기 때문입니다. | |
disabled | boolean = false` | disabled prop은 field prop에서 반환됩니다. 제어 입력 필드는 비활성화되며, 그 값은 제출 데이터에서 제외됩니다. |
Return
다음 표는 Controller
가 생성하는 프로퍼티에 대한 정보를 담고 있습니다.
Object Name | Name | Type | Description |
---|---|---|---|
field | onChange | (value: any) => void | 입력 값을 라이브러리에 전달하는 함수. 이 함수는 입력 필드의 onChange prop에 할당해야 하며, 값은 undefined 가 될 수 없습니다. 이 prop은 formState를 업데이트하므로, setValue나 필드 업데이트와 관련된 다른 API를 직접 호출하는 것은 피해야 합니다. |
field | onBlur | () => void | 입력의 onBlur 이벤트를 라이브러리로 전달하는 함수. 이 함수는 입력 필드의 onBlur prop에 할당되어야 합니다. |
field | value | unknown | 제어 컴포넌트의 현재 값. |
field | disabled | boolean | 입력 필드의 비활성화 상태. |
field | name | string | 등록된(registered) 입력 필드의 이름. |
field | ref | React.ref | 입력 필드를 hook form에 연결하는데 사용하는 ref. hook form이 에러가 발생한 입력 필드에 포커스를 맞출 수 있도록 컴포넌트 입력 필드 ref에 ref 를 할당하세요. |
fieldState | invalid | boolean | 현재 입력 필드의 유효하지 않은 상태. |
fieldState | isTouched | boolean | 현재 제어 입력 필드의 터치 상태. |
fieldState | isDirty | boolean | 현재 제어 입력 필드의 변경 상태. |
fieldState | error | object | 해당 특정 입력 필드의 에러. |
formState | isDirty | boolean | 사용자가 입력을 수정하면 true 로 설정합니다.
|
formState | dirtyFields | object | 사용자가 수정한 필드를 담고 있는 객체. 라이브러리가 defaultValues 와 비교할 수 있도록, 모든 입력 필드의 기본값을 useForm을 통해 제공하세요.
|
formState | touchedFields | object | 사용자가 상호작용한 모든 입력 요소를 포함하는 객체. |
formState | defaultValues | object | useForm의 기본값에 설정된 값 또는 reset API를 통해 업데이트된 기본값. |
formState | isSubmitted | boolean | 폼이 제출된 후 true 로 설정합니다. reset 메서드가 호출될 때까지 true 로 유지됩니다. |
formState | isSubmitSuccessful | boolean | 런타임 에러 없이 폼이 성공적으로 제출되었음을 나타냅니다. |
formState | isSubmitting | boolean | 현재 폼이 제출 중이면 true , 그렇지 않으면 false 로 설정합니다. |
formState | isLoading | boolean | 폼이 현재 비동기 기본값을 로딩 중이면 true 로 설정합니다.중요: 이 prop은 비동기 defaultValues 에만 적용됩니다. |
formState | submitCount | number | 제출된 횟수. |
formState | isValid | boolean | 에러가 없는 경우 true 로 설정합니다.setError 는 formState의 isValid 값에 영향을 주지 않으며, isValid 는 항상 전체 폼 유효성 검사 결과를 통해 계산됩니다. |
formState | isValidating | boolean | 유효성 검사를 하고 있는 동안 true 로 설정합니다. |
formState | errors | object | 필드 에러를 담고 있는 객체. 에러 메세지를 쉽게 가져올 수 있도록 도와주는 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))}><Controllercontrol={control}name="ReactDatepicker"render={({ field: { onChange, onBlur, value, ref } }) => (<ReactDatePickeronChange={onChange} // hook form에 값 전달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><Controllercontrol={control}rules={{required: true,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="First name"onBlur={onBlur}onChangeText={onChange}value={value}/>)}name="firstName"/>{errors.firstName && <Text>This is required.</Text>}<Controllercontrol={control}rules={{maxLength: 100,}}render={({ field: { onChange, onBlur, value } }) => (<TextInputplaceholder="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) 과정을 처리하도록 설계되어 있습니다.<Controllername="test"render={({ field }) => {// return <input {...field} {...register('test')} />; ❌ double up the registrationreturn <input {...field} /> // ✅}}/> -
onChange
이벤트에서 값을 변환하여 hook form에 전달될 값을 원하는 형태로 변경할 수 있습니다.<Controllername="test"render={({ field }) => {// sending integer instead of string.return (<input{...field}onChange={(e) => field.onChange(parseInt(e.target.value))}/>)}}/>
지원해 주셔서 감사합니다
프로젝트에서 React Hook Form이 유용하다고 생각하신다면, 스타를 눌러 지원해 주시길 부탁드립니다.