잊기 전에 복습 들어간다~~
React Hook Form은 React 내에서 Form을 쉽게 제어하고 손쉽게 유효성 검사를 처리하도록 도와주는 라이브러리.
다른 종속성이 없는 최소한의 라이브러리로 구성되어 있어 성능이 뛰어나고 사용이 간편하다.
<form>,<input>,<button>
으로 구현해보기- app.tsx
function App() {
return (
<>
<GlobalStyle />
<TodoList />
</>
);
}
- ToDoList.tsx
function ToDoList() {
const [toDo, setToDo] = useState("");
const [toDoError, setToDoError ] = useState("");
const onChange = (event: React.FormEvent<HTMLInputElement>) => {
const {
currentTarget: { value },
} = event;
setToDoError("");
setToDo(value);
};
const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if(toDo.length < 10) {
return setToDoError('TO DO SHOULD BE LONGER');
}
};
return (
<div>
<form onSubmit={onSubmit}>
<input onChange={onChange} value={toDo} placeholder="Write a to do" />
<button>Add</button>
<toDoError !== "" ? toDoError : null }
</form>
</div>
);
}
input
이 한 개만 있으니 이정도지만,input
이 하나가 아니라 여러개라면 ? ;; npm install react-hook-form
import { useForm } from "react-hook-form";
const { register, watch, handleSubmit } = useForm();
{...register("사용하고 싶은 이름")}
입력 필드에는 name 속성이 있어야 하며 해당 값은 고유해야 함data
라는 인자를 넘겨준다.form의 입력값을 추적
React hook form 을 사용하면 value
와 onChange
로 각 입력 필드에 대한 처리를 추가할 필요가 없고, state
를 직접 관리할 필요가 없다!
function ToDoList() {
const { register, watch, handleSubmit } = useForm();
return (
<div>
<form>
<input {...register("email")} placeholder="Email" />
// → ... : 기존의 register 함수가 반환하는 객체들을 input 에 props 로 줄 수 있다.
<input {...register("firstName")} placeholder="First Name" />
<input {...register("lastName")} placeholder="Last Name" />
<input {...register("username")} placeholder="Username" />
<input {...register("password")} placeholder="Password" />
<input {...register("password1")} placeholder="Password1" />
<button>Add</button>
</form>
</div>
);
}
handleSubmit
으로 기존 코드의 validation
, preventDefault
를 대체해줄 수 있다?const { register, watch, handleSubmit } = useForm();
const onValid = (data:any) => {
console.log(data);
}
return (
<div>
<form onSubmit={handleSubmit(onValid)}>
<input {...register("email")} placeholder="Email" />
handleSubmit
함수가 실행 될 때 진행되는데,data
가 출력되지만,formState
를 사용하면 된다.<input {...register("email", {
required: true,
minLength: 10} <<<----
)} placeholder="Email" />
<input {...register("firstName", {
required:"Frist Name is required!" } <<<----
)} placeholder="First Name" />
<input
{...register("password1", {
required: "Password is required", <<<-----
minLength: {
value: 5,
message: "Your password is too short.",
},
})}
placeholder="Password1"
/>
required: true
라고 주어도 되지만,required: "Password is required"
메시지로 전달해줘도 된다.minLength
의 경우에도 최소 숫자만 적거나(값을 즉시 보내거나),const { register, watch, handleSubmit, formState : {errors} } = useForm();
<input .... />
<span>
{errors?.email?.message}
</span>
required: true
라고 적어줬다면, 띄워지지 않는다. 무조건 메시지가 있어야만 에러 메시지가 띄워진다. interface IFrom {
email : string;
firstname : string;
lastername : string;
username : string;
password : string;
password1 : string;
}
...
const { register, watch, handleSubmit, formState : {errors} } = useForm<IForm>();
// 만약 여기있는 항목들 중에서 필수항목이 아닌게 있다면 ? 을 꼭 붙이기.
const { register, watch, handleSubmit, formState : {errors} }
= useForm<IForm>({
defaultValues : {
email: "@naver.com;
}
});
placeholder
처럼, email 칸에 "@naver.com"을 기본값으로 넣어줄 수 있다.setError
는 특정 값에 직접 에러를 발생시킬 수 있다.const onValid = (data: IFrom) => {
if (data.password!== data.password1) {
setError("password1", {
meesage:"password are not the same",
shouldFocus: true,
})
}
}
패스워드와 패스워드 확인란이 다를 경우 위에 설정한 에러 메시지가 확인되며, form 이 제출되지 않는다.
또한, shouldFocus
를 설정했으므로 password1 에 오류가 있다면 form 의 커서가 password1 으로 옮겨질 것.
내가 원하는 validation 을 추가하려면
... { required: "write here", validate: (value) => ture }
validate
는 함수를 값으로 가지며, 인자로 항목에 쓰여지고 있는 값을 받는다.boolean
or string
문자열validate : (value) => !value.includes("nico"),
validate : (value) => value.includes("nico") ? "no nicos allowed" : true,
validate : {
...
}
React Hook Form 을 사용하여 기존 코드 변경하기
interface IForm {
toDo: string;
}
function ToDoList() {
const { register, handleSubmit, setValue } = useForm<IForm>();
const handleValid = (data: IForm) => {
setValue("toDo", "");
};
return (
<div>
<form onSubmit={handleSubmit(handleValid)}>
<input
{...register("toDo", {
required: "Please write a To Do",
})}
placeholder="Write a to do"
/>
<button>Add</button>
</form>
</div>
);
}
export default ToDoList;