리엑트에서 유저 인풋을 받을때 가장 기본적인 것은 useState을 사용해서 받는것이다.
하지만 이런 방식은 유저가 인풋을 여러개 입력을 하면 할수록 코드가 복잡해지고, 해당 useState에 따른 조건을 하나하나 다 짜줘야 한다는 불편함이 있다.
예를 들어 다음과 같이 toDoList라는 함수에서 유저들한테 toDo값을 받고 입력한 toDo의 길이가 10보다 작을 경우 너무 짧다고 출력한다고 가정해 보자.
function ToDoList() {
const [toDo, setToDo] = useState("");
const [toDoError, setToDoError] = useState("");
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
const {
currentTarget: { value },
} = event;
setToDo(value);
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log(toDo);
if (toDo.length < 10) {
return setToDoError("To do should be longer");
}
console.log("submit");
};
return (
<div>
<form onSubmit={onSubmit}>
<input onChange={onChange} value={toDo} placeholder="Write a to do" />
<button>Add</button>
</form>
</div>
);
}
위 코드와 같이 toDo에 대한 useState, toDoError을 반환해야 하는 에러 조건, toDoError에 해당하는 useState을 지정해주어서, 비교적 간단한 동작이지만 코드가 길어지는 것을 볼 수 있다.
이를 간단하기 위해 React Hook Form을 사용할 수 있다.
const {register, watch, handleSubmit} = useForm();
useForm에서 register 함수를 사용해서 위 코드에 해당하는 onChange 함수를 대신해준다.
아래와 같이 콘솔에 register 함수를 찍어보면
console.log(register("todo"));
위와 같이 onBlur, onChange, ref를 반환한다.
input에 register에서 받은 값들을 props로 아래와 같이 전달을 할 수 있다.
<input {...register("todo")} placeholder="Write a todo"/>
useForm에서 변경되는 것을 함수명 그대로 보고 있는 것이다.
console.log(watch());
아래와 같이 watch 함수를 콘솔에 출력하면, register에서 입력하는 값이 변경될때마다 콘솔에 해당 값을 출력하는 것을 확인할 수 있다.
전에 useState함수를 사용할땐 유저들이 인풋한 값들의 길이는 너무 짧지 않은지와 같은 validation을 직접 조건문을 사용해 처리하여야 했다.
하지만 React Hook Form의 handleSubmit 함수를 사용하면 이 작업 역시 무척 간단해진다.
HandleSubmit 함수를 사용하기 위해서 체크를 하는 onValid 함수를 생성해준다.
const onValid = (data:any) => {}
그리고 폼에 다음과 같이 onSubmit에 handleSubmit을 호출하게 해준다.
<form onSubmit={handleSubmit(onValid)}>
<input {...register("email", {required:true, minLength:10})} placeholder="Email"/>
<input {...register("firstName", {required:true})} placeholder="First Name"/>
<input {...register("lastName", {required:true})} placeholder="Last Name"/>
<input {...register("username", {required:true})} placeholder="Username"/>
<input {...register("password", {required:true})} placeholder="Password"/>
<input {...register("password1", {required:true})} placeholder="Password1"/>
<button>Add</button>
</form>
별도의 조건함수를 작성하지 않았는데 이메일에 minLength가 충족 되지 않았을때 submit이 되지 않는 것을 확인할 수 있다.