React 내에서 Form을 쉽게 제어하고 손쉽게 유효성 검사를 처리하도록 도와주는 라이브러리
적용 예시 ⬇️
import React from "react";
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit, errors } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">이메일</label>
<input type="text" name="email" placeholder="test@email.com" {...register("email"} />
<label htmlFor="password">비밀번호</label>
<input type="password" name="password" ref={register} /> //or {...register("password")}
<button type="submit">Login</button>
</form>
</div>
);
npm install react-hook-form
const { register, handleSubmit, errors } = useForm();
React Hook Form은 form 작업에 사용할 수 있는 useForm hook을 제공합니다. hook은 초기값 설정, 입력 필드 지우기 기능 등을 제공하지만, 제일 중요한 세 가지는 상기의 것
ref로 사용되는 함수로 입력 필드를 React Hook Form에 등록하고 변경 사항에 대해 값을 추적합니다.
<input type="text" name="email" ref={register} />
⭐ 입력 필드에는 name 속성이 있어야 하며 해당 값은 고유해야 한다!
form을 서버로 제출할 때 사용하는 함수입니다.
<form onSubmit={handleSubmit(onSubmit)}>
const onSubmit = (data) => {
console.log(data);
};
유효성 검사를 포함하는 객체입니다.
<input type="text" name="email" ref={register({ required: true})} />
<input
type="password"
name="password"
ref={register({ required: true, minLength: 6 })}
/>
validation를 추가하기 위해서는 각 입력 필드 ref로 전달되는 레지스터 함수에 유효성 검사를 매개변수를 전달합니다.
<input type="text" name="email" ref={register({ required: true})} />
<input
type="password"
name="password"
ref={register({ required: true, minLength: 6 })}
/>
유효성 검사 속성들
이렇게 정의된 속성들에 따라 form이 제출될 때 errors로 유효성 검사 성공여부를 확인할 수 있습니다.
<input
type="text"
name="email"
error={errors.email?.message === undefined ? "" : "error"}
ref={register("email", {
required: {value: true, message:'Email is required.'},
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message: 'Email is not valid.'
}
})}
/>
{errors.email && errors.email.type === "required" && (
<p className="errorMsg">{errors.email?.message}</p>
)}
기본적으로 유효성 검사는 handleSubmit 함수가 실행될 대 진행됩니다. 유효성 검사가 실패하면 React Hook Form은 다음과 같이 처리합니다.
validate 함수를 추가하여 입력 필드에 대한 사용자 지정 유효성 검사를 제공할 수도 있습니다.
const validatePassword = (value) => {
if (value.length < 6) {
return '6자리보다 적게 입력해주세요.';
}
return true;
};
<input
type="password"
name="password"
ref={register({
required: '비밀번호는 필수값입니다.',
validate: validatePassword
})}
/>
const onValid = async (data) => {
if (data.password !== data.passwordConfirm) {
setError(
"passwordConfirm",
{ message: "비밀번호가 다릅니다." },
{ shouldFocus: true }
);
}
try {
await axios
.post("http://localhost:3001/signup", data)
.then((data) => {
Toast.fire({
title: "회원가입 성공!",
icon: "success",
customClass: {
icon: "icon-class",
container: "my-swal",
},
});
setSignupOpen(false);
dispatch(modalOpen());
});
} catch (error) {
console.error(error);
}
};
<ModalInputBox onSubmit={handleSubmit(onValid)}>
<div>
<label htmlFor="password">비밀번호</label>
<input
id="password"
type="password"
placeholder="8자 이상의 숫자, 영대소문자, 특수문자 포함"
{...register("password", {
required: "비밀번호를 입력해주세요.",
pattern: {
value: /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,25}$/,
message:
"숫자+영문자+특수문자 조합으로 8자리 이상 입력해주세요!",
},
})}
/>
<ErrorBox>
{errors?.email?.message === undefined ? null : (
<BiErrorCircle />)
}{errors?.password?.message}
</ErrorBox>
</div>
</ModalInputBox>
<div>
<label htmlFor="email">이메일</label>
<input
id="email"
type="text"
placeholder="address@email.com"
{...register("email", {
required: "이메일을 입력해주세요.",
pattern: {
value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
message:"올바른 이메일 형식이 아닙니다.",
},
})}
/>
<ErrorBox>
{errors?.email?.message === undefined ? null : (
<BiErrorCircle />)
}{errors?.email?.message}
</ErrorBox>
</div>