react-hook-form은 React 환경에서 form을 쉽게 다루기 위해 만들어진 라이브러리에요.

간단한 예제와 함께 사용법을 살펴볼게요.
<form>
<input type="text" placeholder="id" />
<input type="email" placeholder="email" />
<button>제출</button>
</form>

단순한 로그인 form이에요.
form 제출 시 id와 email을 콘솔에 출력해 볼게요.
export default function Home() {
const [id, setId] = useState("");
const [email, setEmail] = useState("");
const onIdChange = (event) => {
const {
currentTarget: { value },
} = event;
setId(value);
};
const onEmailChange = (event) => {
const {
currentTarget: { value },
} = event;
setEmail(value);
};
const onSubmit = (event) => {
event.preventDefault();
console.log(id, email);
};
return (
<div style={{ width: "500px", margin: "0 auto", marginTop: "200px" }}>
<form onSubmit={onSubmit}>
<input type="text" placeholder="id" onChange={onIdChange} value={id} />
<input
type="email"
placeholder="email"
onChange={onEmailChange}
value={email}
/>
<button>제출</button>
</form>
</div>
);
}

원래 form 제출 시 id와 email을 받으려면 input 태그에 onChange와 value 속성을 준 후 onChange시 event 인자의 value로 id state를 수정해줘야 했어요.
또 button의 onSubmit 함수 안에서도 preventDefault() 함수를 실행해 페이지 새로고침을 막는다거나 유효성 검사가 필요하다면 이를 위한 조건문들을 작성해주어야 했죠.
input의 개수에 따라 필요한 state와 onChange 함수도 늘어나므로 코드가 복잡해집니다.
그 대신 react-hook-form을 사용해 볼게요.
export default function Home() {
const { register, handleSubmit } = useForm();
const onValid = (data) => {
console.log(data);
};
return (
<div style={{ width: "500px", margin: "0 auto", marginTop: "200px" }}>
<form onSubmit={handleSubmit(onValid)}>
<input {...register("id")} type="text" placeholder="id" />
<input {...register("email")} type="email" placeholder="email" />
<button>제출</button>
</form>
</div>
);
}
훨씬 간단해졌죠.
우선 useForm 훅으로부터 register과 handleSubmit 함수를 받습니다.
register
register는 name을 인자로 받아 input을 관리할 수 있는 속성을 모아놓은 오브젝트를 리턴하는데요,
이것을 구조분해할당을 이용해 input에 풀어줍니다.
handleSubmit
handleSubmit는 form의 onSubmit 속성에 전달하는 함수로, form이 성공적으로 제출되었을 때 실행할 함수를 인자로 받습니다.
그리고 그 함수에 인자로 data를 사용할 수 있게 하는데,
여기서는 onValid 함수를 만들어 data를 출력해 볼게요.

useForm은 register, handleSubmit 외에도 다양한 함수를 지원합니다.
그 중 자주 사용되는 reset과 formState를 알아볼게요.
그 외의 사용법은 공식 문서에서 확인할 수 있습니다.
reset은 form 제출 후에 input을 비우고 싶을 때 사용되요.
const { register, handleSubmit, reset } = useForm();
...
<form onSubmit={handleSubmit(onValid)}>
...
<button onClick={() => reset()}>제출</button>
</form>
위와 같이 함수 내에서 reset을 실행하면 register로 등록된 input의 값이 빈 문자열로 초기화됩니다.
formState 오브젝트의 errors는 register된 input의 유효성을 검사하고 싶을 때 사용되요.
예를 들어 로그인 시 id와 email 모두 required를 주고, id는 3글자 이상으로 입력해야하는 조건이 있다고 하면
register에 관련 매개변수를 함께 전달 후 errors.id 혹은 errors.email에서 에러를 확인할 수 있어요.
코드로 작성해 볼게요.
import { useForm } from "react-hook-form";
export default function Home() {
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm();
const onValid = (data) => {
console.log(data);
};
return (
<div style={{ width: "500px", margin: "0 auto", marginTop: "200px" }}>
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("id", {
required: "아이디를 입력해 주세요.",
minLength: {
value: 5,
message: "아이디는 5글자 이상이어야 합니다.",
},
})}
type="text"
placeholder="id"
/>
<span style={{ color: "red" }}>{errors?.id?.message}</span>
<input
{...register("email", { required: "이메일을 입력해 주세요." })}
type="email"
placeholder="email"
/>
<span style={{ color: "red" }}>{errors?.email?.message}</span>
<button onClick={() => reset()}>제출</button>
</form>
</div>
);
}
useForm에서 formState 오브젝트 안 errors를 사용했고,
input 안의 register의 두 번째 매개변수로 유효성 설정을 해주었어요.
id에는 required와 함께 에러메시지를, minLength의 value와 message를 주었어요.
email도 마찬가지로 required를 주고,
각 input 밑에 span 태그를 사용해 erros가 존재한다면, 그곳에 등록된 name이 존재한다면
message를 띄우게 했어요.

input 태그의 구체적인 유효성 검사와 함께 error message를 편집할 수 있습니다.