React.js/React-hook-form
react-hook-form에서 useController 커스텀 훅 사용
Dev갱이
2024. 6. 25. 19:20
728x90
input 타입의 time 필드가 여러개가 존재 할때 재사용할 수 있는 컴포넌트를 만들때 useController 커스텀훅을 사용하면 좋을것 같았다.
재사용 컴퍼넌트를 만들때 useController에서 사용하고자 하는 props를 정의 해주어야 한다.
control, name, validationOptions
// FieldTime.tsx
import React from 'react';
import { Control, Path, RegisterOptions, useController } from 'react-hook-form';
import Field from '../Field';
interface Props<T extends Record<string, any>> {
control: Control<T>;
name: Path<T>;
validationOptions?: Omit<
RegisterOptions<T, Path<T>>,
'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'
>;
}
const FieldTime = <T extends Record<string, any>>(props: Props<T>) => {
const { control, name, validationOptions } = props;
const {
field,
fieldState: { invalid, isTouched, isDirty, error },
formState: { touchedFields, dirtyFields },
} = useController({
name,
control,
rules: { ...validationOptions },
});
return (
<Field
fieldClass={'inline_input'}
labelText={'시작시간'}
onChange={field.onChange}
name={field.name}
value={field.value}
className="w-full md:text-base text-sm"
type="time"
error={error && error}
/>
);
};
export default FieldTime;
이렇게 재사용 컴퍼넌트를 만들고 난 후에 부모 컴퍼넌트에서 useForm을 이용하여 register와 control을 둘다 사용할 수 있다.
// 부모 컴포넌트
const {
register,
formState: { errors, isValid },
handleSubmit,
reset,
getValues,
watch,
control,
} = useForm<{
eventName: string;
eventDescription: string;
eventStartTime: string;
}>({
mode: 'onChange',
});
... 중략
<div className={styles.field_container}>
<Field
fieldClass={'inline_input'}
labelText={'이벤트 이름'}
{...register('eventName', {
required: '이벤트 이름은 필수입니다!',
minLength: {
value: 2,
message: '최소 이름은 2자 이상입니다.',
},
})}
placeholder="이벤트 이름을 입력 해주세요!"
error={errors.eventName}
></Field>
<FieldWithTextarea
fieldClass={'inline_textarea'}
labelText={'이벤트 설명'}
{...register('eventDescription', {
maxLength: {
value: 1000,
message: '최대 1000자까지 가능합니다',
},
})}
placeholder="상세 정보를 추가하세요"
error={errors.eventDescription}
></FieldWithTextarea>
{/* <Field
fieldClass={'inline_input'}
labelText={'시작시간'}
{...register('eventStartTime', {
required: '시작시간을 필수입니다!',
})}
className="w-full md:text-base text-sm"
type="time"
error={errors.eventStartTime}
/> */}
<FieldTime
control={control}
name="eventStartTime"
labelText="시작시간"
validationOptions={{
required: '시작시간을 필수입니다!',
}}
></FieldTime>
</div>
... 중략
register를 사용하거나 control로 재사용 컴포넌트를 사용해서 사용하거나 할 수 있어서 react-hook-form이 굉장히 강력한것 같다.
Reference
https://react-hook-form.com/docs/usecontroller
useController
Performant, flexible and extensible forms with easy-to-use validation.
react-hook-form.com
https://velog.io/@boyeon_jeong/React-Hook-Form-Controller-useController-y6v2mfc9
[React Hook Form] mui와 같이 사용하기 | Controller, useController
제어 컴포넌트(https://legacy.reactjs.org/docs/forms.htmlReact에서 제어 컴포넌트는 폼 요소뿐만 아니라 일반적인 컴포넌트에서도 사용될 수 있습니다. 그러나 폼 요소를 제어 컴포넌트로 사용하는 것이
velog.io
728x90