
1. 사용자가 이메일, 비밀번호 입력
↓
2. react-hook-form이 입력값 관리
↓
3. 제출 버튼 클릭
↓
4. 유효성 검사 (빈 값 체크)
↓
5. API 호출로 회원가입
↓
6. 성공하면 알림 띄우고 로그인 페이지로 이동
"폼 관리를 쉽게 해주는 라이브러리"
// 귀찮음!
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [emailError, setEmailError] = useState("");
const [passwordError, setPasswordError] = useState("");
const handleEmailChange = (e) => {
setEmail(e.target.value);
// 유효성 검사 코드...
};
const handlePasswordChange = (e) => {
setPassword(e.target.value);
// 유효성 검사 코드...
};
문제점:
const { register, handleSubmit, formState: { errors } } = useForm<SignupProps>();
장점:
const {
register,
handleSubmit,
formState: { errors },
} = useForm<SignupProps>();
"이 input을 react-hook-form이 관리하게 해줘"
<InputText
placeholder="이메일"
inputType="email"
{...register("email", { required: true })}
/>
해석:
register("email"): 이 input의 name을 "email"로 등록{ required: true }: 필수 입력값{...register()}: input에 필요한 props 자동 연결실제로는 이렇게 변환됨:
<input
name="email"
ref={...}
onChange={...}
onBlur={...}
/>
"폼 제출 처리해줘"
<form onSubmit={handleSubmit(onSubmit)}>
동작 순서:
1. 사용자가 제출 버튼 클릭
2. handleSubmit이 유효성 검사 실행
3. 에러 있으면 → errors에 저장, 제출 안 함
4. 에러 없으면 → onSubmit 함수 실행
"어떤 input에 에러가 있는지 알려줘"
{errors.email && (
<p className="error-text">이메일을 입력해주세요.</p>
)}
의미:
errors.email이 있으면 (= email이 비어있으면)"다른 페이지로 이동시켜줘"
const navigate = useNavigate();
// 사용
navigate("/login"); // /login 페이지로 이동
Link vs navigate:
// Link: 클릭할 버튼/텍스트가 있을 때
<Link to="/login">로그인하기</Link>
// navigate: 코드에서 자동으로 이동시킬 때
if (회원가입성공) {
navigate("/login"); // 자동 이동
}
const showAlert = useAlert();
// 사용
showAlert("회원가입이 완료되었습니다.");
커스텀 Hook이란?
useAlert 내부는 아마 이렇게 생김:
// hooks/useAlert.ts
export function useAlert() {
return (message: string) => {
alert(message); // 또는 토스트 메시지
};
}
const {
register,
handleSubmit,
formState: { errors },
} = useForm<SignupProps>();
SignupProps 타입으로 폼 데이터 타입 지정<InputText
placeholder="이메일"
inputType="email"
{...register("email", { required: true })}
/>
register로 input 연결required: true로 필수값 지정{errors.email && (
<p className="error-text">이메일을 입력해주세요.</p>
)}
errors.email이 있으면 에러 메시지 표시<form onSubmit={handleSubmit(onSubmit)}>
handleSubmit이 유효성 검사onSubmit 함수 실행const onSubmit = (data: SignupProps) => {
signup(data).then((res) => {
showAlert("회원가입이 완료되었습니다.");
navigate("/login");
});
};
data 내용:
{
email: "user@example.com",
password: "1234"
}
동작:
1. signup(data): API 호출
2. .then(): 성공하면
3. showAlert(): 알림 표시
4. navigate(): 로그인 페이지로 이동
// const [email, setEmail] = useState("");
// const [password, setPassword] = useState("");
왜 안 쓰냐?
export interface SignupProps {
email: string;
password: string;
}
의미:
사용 위치:
useForm<SignupProps>() // 폼 타입 지정
onSubmit(data: SignupProps) // 파라미터 타입 지정
1. 사용자가 아무것도 입력 안 하고 제출
↓
2. handleSubmit이 유효성 검사
↓
3. required: true 위반 감지
↓
4. errors.email = true, errors.password = true
↓
5. 에러 메시지 표시 (onSubmit 실행 안 됨)
1. 사용자가 이메일, 비밀번호 입력
↓
2. 제출 버튼 클릭
↓
3. handleSubmit이 유효성 검사 (통과)
↓
4. onSubmit 함수 실행
↓
5. signup API 호출
↓
6. 성공하면 알림 + /login으로 이동
register: input 등록handleSubmit: 제출 처리errors: 에러 상태"폼 만들 땐 react-hook-form 쓰면 편함!"