보통 회원가입 페이지를 만들면 id, passwor, email 등등 많은 값들이 필요하게 되고, useState 훅을 이용해 만들게 되면, onChange
핸들러를 그 수에 맞게 만들고,validation
함수도 그에 맞게 만들어야 함.그럼 자연스럽게 해당 값들을 관리할 state
들이 늘어나게 됨.
그에 따른 문제점
React Hook Form 라이브러리는 React에서 사용자로부터 데이터를 수집하는 form을 쉽게 관리하기 위한 라이브러리
Reack Hook Form은 React hooks를 사용하여 폼을 처리하기 때문에 사용하기 간단한 편이며 폼을 처리하는데 필요한 기능을 쉽게 구현할 수 있음
React Hook Form은 폼처리를 위해 불필요한 렌더링을 최소화하고 성능을 향상시키기 위해 최적화 되어있어 성능 문제를 방지할 수 있음
npm install react-hook-form
export type UseFormProps<TFieldValues extends FieldValues = FieldValues, TContext = any> = Partial<{
mode: Mode;
reValidateMode: Exclude<Mode, 'onTouched' | 'all'>;
defaultValues: DefaultValues<TFieldValues>;
resolver: Resolver<TFieldValues, TContext>;
context: TContext;
shouldFocusError: boolean;
shouldUnregister: boolean;
shouldUseNativeValidation: boolean;
criteriaMode: CriteriaMode;
delayError: number;
}>;
const model = useForm({
mode: "onChange",
defaultValues: {},
});
export type UseFormReturn<TFieldValues extends FieldValues = FieldValues, TContext = any> = {
watch: UseFormWatch<TFieldValues>;
getValues: UseFormGetValues<TFieldValues>;
getFieldState: UseFormGetFieldState<TFieldValues>;
setError: UseFormSetError<TFieldValues>;
clearErrors: UseFormClearErrors<TFieldValues>;
setValue: UseFormSetValue<TFieldValues>;
trigger: UseFormTrigger<TFieldValues>;
formState: FormState<TFieldValues>;
resetField: UseFormResetField<TFieldValues>;
reset: UseFormReset<TFieldValues>;
handleSubmit: UseFormHandleSubmit<TFieldValues>;
unregister: UseFormUnregister<TFieldValues>;
control: Control<TFieldValues, TContext>;
register: UseFormRegister<TFieldValues>;
setFocus: UseFormSetFocus<TFieldValues>;
};
해당 함수를 통해 input태그를 다룸
첫번째 매개변수: input의 name
두번째 매개변수: options 객체(유효성 검사를 위한 프로퍼티)
<input
type="text"
{...register("email", {
pattern: {
value:
/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i,
message: "이메일 형식에 맞지 않습니다.",
},
})}
/>;
const {id, name, pwd, ...watch} = watch(); //전체 필드를 리턴
const id = watch("id");
{watch("occupation") === "professor" ? (
<Row>
<Label>phone: </Label>
<ControlInputText<IForm> control={control} name="phone" />
</Row>
) : null
}
const handleEvent = (event) => {
const value = getValues("name");
setState(value);
}
react-hook-form
패키지로 부터 useForm()
훅(hook) 함수를 불러온 후, 컴포넌트 함수 안에서 이 함수를 호출함register()
함수와 handleSubmit()
함수를 얻을 수 있음register()
: input 요소를 등록하는 함수로 각각의 input 요소에 대한 Reference를 생성하고 유효성 검사를 위한 다양한 옵션을 전달할 수 있음handleSubmit()
: 폼(Form)을 제출할 때 호출되는 함수로 폼 데이터를 수집하고, 폼 내에 인풋 요소에 대한 유효성 검사를 실행함import {useForm} from 'react-hook-form'
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
formState
속성의 errors
객체에 오류 내용이 저장됨
<s.SignForm onSubmit={handleSubmit(onSubmit)}>
<s.SignLabel>아이디</s.SignLabel>
<s.SignInput type="text" name="uid" placeholder='4~15자 이내로 작성해주세요'
{errors.uid && <span className="error">{errors.uid.message}</span>}
<s.SignLabel>비밀번호</s.SignLabel>
<s.SignInput type="password" name="password" placeholder='최소 6자 이상(알파벳, 숫자 필수)'
{...register('password',
{required: '비밀번호를 입력하세요',
pattern: {
value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/,
message: '알파벳과 숫자를 포함한 최소 6자 이상이어야 합니다',
}
})}/>
{errors.password && <span className="error">{errors.password.message}</span>}
<s.SignLabel>이메일</s.SignLabel>
<s.SignInput type="email" name="email" placeholder='festivalholic@gmail.com'
{...register('email', {
required: '이메일을 입력하세요',
pattern: {
value: /^[A-Za-z0-9]([-_.]?[A-Za-z0-9])*@[A-Za-z0-9]([-_.]?[A-Za-z0-9])*\.[A-Za-z]{2,3}$/,
message: '이메일 형식을 확인해주세요',
}
})}/>
{errors.email && <span className="error">{errors.email.message}</span>}
<s.SignButton>회원가입</s.SignButton>
</s.SignForm>
(참고) https://www.daleseo.com/react-hook-form/
https://tech.osci.kr/introduce-react-hook-form/