컴포넌트를 분리하면서, 중첩된 컴포넌트에서 useForm을 사용해서 유효성 검사를 구현하려 했으나, 작동하지 않았다.
그래서 공식 사이트를 찾아 보다 FormProvider와 useFormContext를 통해 구현하기로 했다.
요약
const methods = useForm({
defaultValues: {
email: "",
password: "",
},
mode: "onChange",
});
FormProvider
로 감싸주고 methods
를 props
로 전달해 준다. <FormProvider {...methods}>
<Form onSubmit={methods.handleSubmit((data) => onLogIn(data))}>
<AuthInput
validation={{
pattern: {
value: emailRegex,
message: "올바른 형식의 이메일이 아닙니다.",
},
required: {
value: true,
message: "필수 입력 값입니다.",
},
}}
placeholder="이메일"
type="text"
name="email"
/>
<AuthInput
validation={{
pattern: {
value: passwordRegex,
message:
"비밀번호는 최소 6자 이상, 숫자와 영문자를 모두 포함해야 합니다.",
},
required: {
value: true,
message: "필수 입력 값입니다.",
},
}}
placeholder="비밀번호"
type="password"
name="password"
/>
<Button type="submit">로그인</Button>
</Form>
</FormProvider>
const AuthInput = ({ placeholder, type, name, validation }: any) => {
const {
register,
formState: { errors },
} = useFormContext<any>();
const error = errors[name];
return (
<>
<Label htmlFor={name}>{placeholder}</Label>
{/* placeholder는 스크린 리더가 읽지 못할 수도 있기 때문에 label를 추가해주어야 한다. */}
<Input
placeholder={placeholder}
type={type}
{...register(name, validation)}
id={name}
name={name}
/>
<ErrorMessage>{error && error?.message?.toString()}</ErrorMessage>
</>
);
};
useForm에 mode라는 속성을 추가하면 실시간(onChange)이나 제출 시(onSubmit), input에서 벗어났을 때(onBlur) 등의 시점에 유효성 검사를 실시할 수 있다.
const methods = useForm({
defaultValues: {
email: "",
password: "",
},
mode: "onChange",
});```
참고:
[FromProvider](https://react-hook-form.com/docs/formprovider)