[REACT] React Hook Form - Form Validation
학습일 : 2023. 04. 17
Form Validation 을 알아보도록 하겠다.
두가지 경우를 살펴보자.
1. onSubmit 으로 handleSubmit 함수를 주었을 경우
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("email", { required: true })}
placeholder="email을 입력해주세요."
/>
2. 그냥 html 태그 안에 required를 주었을 경우
<form onSubmit={handleSubmit(onValid)}>
<input {...register("email")} required placeholder="email을 입력해주세요." />
</form>
이 둘의 차이는 무엇일까?
둘다 required가 똑같이 적용되는 것인데 말이다.
2번 (html 태그안 required를 주는 경우)는 개발자도구를 켜서 강제로 required를 삭제하면
정상적으로 submit이 되고 form 데이터가 들어가게 되는 의도치 않은 현상이 발생한다.
기본적으로는 email을 작성하지 않으면 html로부터 email을 적으라는 등의 소리를 듣게는 되겠지만
문제는 사용자가 이걸 지원하지 않는 환경인 브라우저에 있거나,
모바일에서 본다던가 하는 등의 상황에선 문제가 생긴다는 것이다.
따라서 html에 의지하는 대신, 자바스크립트에서 validation을 하도록 한다.
전체코드
<ToDoList.tsx>
onSubmit 으로 handleSubmit 함수를 전달
javascript로 required:true 를 주도록 한다.
import { useForm } from "react-hook-form";
function ToDoList() {
const { register, handleSubmit } = useForm();
const onValid = (data: any) => {
console.log(data);
};
return (
<div>
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("email", { required: true })}
placeholder="email을 입력해주세요."
/>
<input
{...register("firstname", { required: true })}
placeholder="firstname을 입력해주세요."
/>
<input
{...register("lastname", { required: true })}
placeholder="lastname을 입력해주세요."
/>
<input
{...register("username", { required: true })}
placeholder="username을 입력해주세요."
/>
<input
{...register("password", { required: true })}
placeholder="password을 입력해주세요."
/>
<input
{...register("password1", { required: true })}
placeholder="password1을 입력해주세요."
/>
<button>추가</button>
</form>
</div>
);
}
export default ToDoList;
실행결과
적어주지 않는 곳에 자동으로 focus 가 되고
모두 적어주고 추가버튼을 눌러줬을 경우
form이 제대로 submit됨을 볼 수 있음.
React Hook Form 사용 안하고
그냥 자바스크립트로만 적어줬으면
한나절이나 걸렸을 것인데..
절레절레
<input
{...register("username", { required: true, minLength:10 })}
placeholder="username을 입력해주세요."
/>
이것과
if (toDo.length < 10) {
return setToDoError("To do should be longer~~");
}
이 작업이 같다고 보면 된다.
required:true 적어준 옆으로 추가하고자 하는 조건을 입력해주면 된다.
그렇다면 에러는 어떻게 발생시키는가?
<ToDoList.tsx>
useForm 의 formState 라는 property를 하나 더 받으면 된다.
그리고 콘솔에 에러를 찍어보자.
function ToDoList() {
const { register, handleSubmit, formState } = useForm();
const onValid = (data: any) => {
console.log(data);
};
// formState를 이용하여 error 표시하기
console.log(formState.errors);
return (
<div>
<form
style={{
display: "flex",
flexDirection: "column",
}}
onSubmit={handleSubmit(onValid)}
>
<input
{...register("email", { required: true })}
placeholder="email을 입력해주세요."
/>
<input
{...register("firstname", { required: true })}
placeholder="firstname을 입력해주세요."
/>
<input
{...register("lastname", { required: true })}
placeholder="lastname을 입력해주세요."
/>
<input
{...register("username", { required: true, minLength: 3 })}
placeholder="username을 입력해주세요."
/>
<input
{...register("password", { required: true, minLength: 10 })}
placeholder="password을 입력해주세요."
/>
<input
{...register("password1", { required: true, minLength: 10 })}
placeholder="password1을 입력해주세요."
/>
<button>추가</button>
</form>
</div>
);
}
export default ToDoList;
콘솔에 찍어보면
에러가 발생한 것들이 다 표시되고
에러가 있다는 사실 뿐만 아니라 어떤 종류의 에러가 생겼는지도 표시가 된다.
<input
{...register("password1", {
required: true,
minLength: { value: 5, message: "Your password is too short!" },
})}
placeholder="password1을 입력해주세요."
/>
이 경우 password1 input에 에러가 발생했을 경우(minLength가 5가 안되어서 발생한 에러)
적어준 메시지가 콘솔에 찍히게 된다.
전체 코드
<ToDoList.tsx>
import { useForm } from "react-hook-form";
function ToDoList() {
const { register, handleSubmit, formState } = useForm();
const onValid = (data: any) => {
console.log(data);
};
// formState를 이용하여 error 표시하기
console.log(formState.errors);
return (
<div>
<form
style={{
display: "flex",
flexDirection: "column",
}}
onSubmit={handleSubmit(onValid)}
>
<input
{...register("email", { required: true })}
placeholder="email을 입력해주세요."
/>
<input
{...register("firstname", { required: true })}
placeholder="firstname을 입력해주세요."
/>
<input
{...register("lastname", { required: true })}
placeholder="lastname을 입력해주세요."
/>
<input
{...register("username", { required: true, minLength: 3 })}
placeholder="username을 입력해주세요."
/>
<input
{...register("password", { required: true, minLength: 10 })}
placeholder="password을 입력해주세요."
/>
<input
{...register("password1", {
required: true,
minLength: { value: 5, message: "Your password is too short!" },
})}
placeholder="password1을 입력해주세요."
/>
<button>추가</button>
</form>
</div>
);
}
export default ToDoList;
실행결과
입력하지 않은 곳이 에러가 발생하여 콘솔에 찍혀 나오고
마지막 password1의 경우 5글자가 안될 경우 에러 메시지가 콘솔에 찍혀나오게 됨을
확인할 수 있다.