</> Controller
: Component
React Hook Form은 비제어 컴포넌트와 네이티브 입력을 기본으로 사용하지만, React-Select, AntD, MUI와 같은 외부 제어 컴포넌트를 사용해야 할 때가 있습니다. 이 래퍼 컴포넌트는 이러한 컴포넌트를 더 쉽게 다룰 수 있게 도와줍니다.
Props
아래 표는 Controller
의 인자에 대한 정보를 담고 있습니다.
이름 | 타입 | 필수 여부 | 설명 |
---|---|---|---|
name | FieldPath | ✓ | 입력 필드의 고유한 이름입니다. |
control | Control | control 객체는 useForm 을 호출하여 얻을 수 있습니다. FormProvider 를 사용할 때는 선택 사항입니다. | |
render | Function | 이는 렌더 프로퍼티입니다. React 엘리먼트를 반환하는 함수로, 컴포넌트에 이벤트와 값을 연결할 수 있는 기능을 제공합니다. 이는 비표준 프로퍼티 이름을 가진 외부 제어 컴포넌트와의 통합을 단순화합니다. 자식 컴포넌트에 onChange , onBlur , name , ref , value 를 제공하며, 특정 입력 상태를 포함하는 fieldState 객체도 제공합니다. | |
defaultValue | unknown | 중요: useForm 에서 defaultValue 또는 defaultValues 에 undefined 를 적용할 수 없습니다.
| |
rules | Object | register 옵션과 동일한 형식의 유효성 검사 규칙입니다. 여기에는 다음이 포함됩니다:required, min, max, minLength, maxLength, pattern, validate | |
shouldUnregister | boolean = false` | 컴포넌트가 언마운트된 후 입력 필드가 등록 해제되고, defaultValues 도 제거됩니다.참고: 이 프로퍼티는 useFieldArray 와 함께 사용할 때 피해야 합니다. 입력 필드가 언마운트/재마운트 및 재정렬된 후 unregister 함수가 호출되기 때문입니다. | |
disabled | boolean = false` | disabled 프로퍼티는 field 프로퍼티에서 반환됩니다. 제어된 입력 필드는 비활성화되며, 제출 데이터에서 해당 값이 제외됩니다. |
반환값
아래 표는 Controller
가 생성하는 속성에 대한 정보를 담고 있습니다.
객체 이름 | 이름 | 타입 | 설명 |
---|---|---|---|
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 | 등록된 입력의 이름입니다. |
field | ref | React.ref | hook form과 입력을 연결하기 위해 사용되는 ref입니다. 컴포넌트의 입력 ref에 ref 를 할당하면 hook form이 오류가 발생한 입력에 포커스를 맞출 수 있습니다. |
fieldState | invalid | boolean | 현재 입력의 유효하지 않은 상태입니다. |
fieldState | isTouched | boolean | 현재 제어된 입력의 터치 상태입니다. |
fieldState | isDirty | boolean | 현재 제어된 입력의 더티 상태입니다. |
fieldState | error | object | 이 특정 입력에 대한 오류입니다. |
formState | isDirty | boolean | 사용자가 어떤 입력을 수정한 후 true 로 설정됩니다.
|
formState | dirtyFields | object | 사용자가 수정한 필드가 담긴 객체입니다. useForm을 통해 모든 입력의 defaultValues를 제공해야 라이브러리가 defaultValues 와 비교할 수 있습니다.
|
formState | touchedFields | object | 사용자가 상호작용한 모든 입력이 담긴 객체입니다. |
formState | defaultValues | object | useForm의 defaultValues 또는 reset API를 통해 업데이트된 defaultValues에 설정된 값입니다. |
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 는 isValid formState에 영향을 미치지 않으며, isValid 는 항상 전체 폼 유효성 검사 결과에 따라 결정됩니다. |
formState | isValidating | boolean | 유효성 검사 중이면 true 로 설정됩니다. |
formState | errors | object | 필드 오류가 담긴 객체입니다. 오류 메시지를 쉽게 가져올 수 있는 ErrorMessage 컴포넌트도 있습니다. |
예제:
웹
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>)}
비디오
아래 비디오는 Controller의 내부 구조와 구현 방식을 보여줍니다.
TIP
-
MUI, AntD, Chakra UI와 같은 외부 제어 컴포넌트를 다룰 때는 각 prop의 역할을 이해하는 것이 중요합니다. Controller는 입력값을 보고하고 설정하는 "스파이" 역할을 합니다.
- onChange: 데이터를 hook form으로 전송
- onBlur: 입력이 상호작용되었음을 보고 (포커스와 블러)
- value: 입력의 초기값과 업데이트된 값을 설정
- ref: 오류 발생 시 입력에 포커스를 줄 수 있도록 함
- name: 입력에 고유한 이름을 부여 아래 Codesandbox 예제를 참고하세요:
- MUI 및 기타 컴포넌트
- Chakra UI 컴포넌트
-
입력을 다시
register
하지 마세요. 이 컴포넌트는 등록 과정을 처리하도록 설계되었습니다.<Controllername="test"render={({ field }) => {// return <input {...field} {...register('test')} />; ❌ 중복 등록return <input {...field} /> // ✅}}/> -
onChange
중에 값을 변환하여 hook form으로 전송되는 값을 커스터마이즈할 수 있습니다.<Controllername="test"render={({ field }) => {// 문자열 대신 정수를 전송return (<input{...field}onChange={(e) => field.onChange(parseInt(e.target.value))}/>)}}/>
여러분의 지원에 감사드립니다
React Hook Form이 프로젝트에서 유용하다면, GitHub에서 스타를 눌러 지원해 주세요.