Controller
</> Controller: ControllerProps
React Hook Form은 비제어 컴포넌트와 네이티브 입력을 지향하지만 React-Select, AntD, MUI 같은 외부 제어 컴포넌트를 사용해야 할 때가 있습니다. 이 래퍼 컴포넌트는 이런 컴포넌트와의 연동을 간소화합니다.
참고: 폼 외부에서 필드 값만 제어하려면 Controller를 사용할 필요가 없습니다. values 옵션을 useForm에서 사용하면 됩니다.
Props(속성)
다음 표는 Controller의 인수를 설명합니다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
name | FieldPath | ✓ | 입력의 고유한 이름입니다. |
control | Control | control 객체이며 useForm을 호출해 얻습니다. FormProvider를 사용하면 선택 사항입니다. | |
render | Function | 렌더 prop입니다. React 요소를 반환하며 컴포넌트에 이벤트와 값을 연결할 수 있게 하는 함수입니다. 표준과 다른 prop 이름을 사용하는 외부 제어 컴포넌트와의 연동을 간소화합니다. 렌더 콜백에 field(onChange, onBlur, name, ref, value 포함), fieldState, formState 객체를 제공합니다. | |
rules | Object | register 옵션과 같은 형식의 검증 규칙이며 다음을 포함합니다.required, min, max, minLength, maxLength, pattern, validate | |
shouldUnregister | boolean = false | 마운트 해제 후 입력의 등록이 해제되고 defaultValues도 제거됩니다. 참고: useFieldArray와 함께 사용하면 입력의 마운트 해제/재마운트와 순서 변경 후 unregister 함수가 호출되므로 이 prop은 사용하지 않는 것이 좋습니다. | |
disabled | boolean = false | v7.46.0부터 disabled prop은 field prop에서 반환됩니다. 제어 입력이 비활성화되고 제출 데이터에서 값이 제외됩니다. | |
defaultValue | unknown | 중요: undefined를 defaultValue 또는 defaultValues에 적용할 수 없으며 후자는 useForm에서 설정합니다.
| |
exact | boolean = true | v7.68.0부터 입력 이름 구독을 정확히 일치시키며 기본값은 true입니다. v7.81.0부터 exact: true이면 상위 경로 중 하나가 설정될 때도 필드가 업데이트되지만 값의 중첩된 하위 경로가 변경될 때는 업데이트되지 않습니다. 자세한 내용은 useController를 참고하세요. |
반환값
다음 표는 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 | 훅 폼을 입력에 연결하는 ref입니다. 훅 폼이 오류가 있는 입력에 포커스할 수 있도록 컴포넌트의 입력 ref에 ref를 할당합니다. 이는 대상 컴포넌트가 ref를 전달하거나(React.forwardRef) MUI의 inputRef처럼 동등한 기능을 노출할 때만 동작합니다. |
fieldState | invalid | boolean | 현재 입력의 유효하지 않은 상태입니다. |
fieldState | isTouched | boolean | 현재 제어 입력의 touched 상태입니다. |
fieldState | isDirty | boolean | 현재 제어 입력의 dirty 상태입니다. |
fieldState | error | object | v7.0.0부터 이 입력에 해당하는 오류입니다. |
formState | isDirty | boolean | 사용자가 입력 중 하나를 수정하면 true로 설정됩니다.
|
formState | dirtyFields | object | 사용자가 수정한 필드를 담은 객체입니다. 라이브러리가 defaultValues와 비교할 수 있도록 useForm을 통해 모든 입력의 defaultValues를 제공해야 합니다.
|
formState | touchedFields | object | 사용자가 상호작용한 모든 입력을 담은 객체입니다. |
formState | defaultValues | object | v7.37.0부터 useForm의 defaultValues에 설정했거나 reset API로 업데이트한 defaultValues 값입니다. |
formState | isSubmitted | boolean | 폼이 제출되면 true로 설정됩니다. true 상태는 reset 메서드를 호출할 때까지 유지됩니다. |
formState | isSubmitSuccessful | boolean | 런타임 오류 없이 폼이 성공적으로 제출되었음을 나타냅니다. |
formState | isSubmitting | boolean | 현재 폼을 제출하고 있으면 true, 그렇지 않으면 false입니다. |
formState | isLoading | boolean | v7.41.0부터 현재 폼이 비동기 기본값을 불러오고 있으면 true입니다.중요: 이 prop은 비동기 defaultValues에만 적용됩니다. |
formState | submitCount | number | 폼을 제출한 횟수입니다. |
formState | isValid | boolean | 폼에 오류가 없으면 true로 설정됩니다.setError는 즉시 isValid를 false로 만듭니다. 이 값 자체는 검증으로부터 파생되지 않으며 다음에 검증이 실행될 때(예: 다음 onChange, 제출, trigger() 호출) 덮어써집니다. |
formState | isValidating | boolean | 검증 중에는 true로 설정됩니다. |
formState | validatingFields | object | v7.51.0부터 비동기 검증 중인 필드를 담습니다. |
formState | errors | object | 필드 오류를 담은 객체입니다. 오류 메시지를 쉽게 가져오는 ErrorMessage 컴포넌트도 있습니다. |
formState | disabled | boolean | v7.48.0부터 폼이 비활성화되면 true로 설정됩니다. disabled prop을 useForm에서 지정합니다. |
formState | isReady | boolean | v7.56.0부터 formState 구독 설정이 준비되면 true로 설정됩니다. |
예시:
Web
import ReactDatePicker from "react-datepicker"
import { TextField } from "@mui/material"
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} // send the value to hook form
onBlur={onBlur} // notify when the input is touched or blurred
selected={value}
/>
)}
/>
<input type="submit" />
</form>
)
}
import ReactDatePicker from "react-datepicker"
import { TextField } from "@mui/material"
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>
)
}
동영상
다음 동영상에서는 Controller의 내부 구조와 구현 방식을 보여 줍니다.