seunghyun Note
React-hook-form 본문
728x90
반응형
기존에 사용했던 제어 컴포넌트들의 반복되는 코드들과 유효성 검증을 한다면 코드가 점점 길어질 것이다.
react에서 컴포넌트 리랜더링이 발생하는 조건 중 하나는 state
가 변했을 때이다.
폼에서는 모든 값이 state
로 연결되어 있으면 하나의 값이 변할 때 마다 여러개의 자식 컴포넌트들에서 무수히 많은 리랜더링이 발생한다. (즉 불필요한 렌더링이 반복된다)
react-hook-form
install
npm i react-hook-form
useForm() 을 사용해서 회원가입 form 만들기
const { register, watch } = useForm();
useForm()
안에는 여러가지 옵션들이 있다.
- register :
register
function은 많은 요청들을 해결해주고 handler 를 대신해준다.
const { onChange, onBlur, name, ref } = register('firstName');
// include type check against field path with the name you have supplied.
<input
onChange={onChange}// assign onChange event
onBlur={onBlur}// assign onBlur event
name={name}// assign name prop
ref={ref}// assign ref prop
/>
// same as above
<input {...register('firstName')} />
- watch :
watch
는 form 의 입력값들의 변화를 관찰 할 수 있게 해주는 함수이다.
function ToDoList() {
const { register, watch } = useForm();
console.log(watch());
return (
<div>
<form>
<input {...register("email")} placeholder="Email" />
<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" />
</form>
</div>
);
}
export default ToDoList;
input에 데이터를 넣으면 아래와 같이 된다.
email: 'cvtcvt007@naver.com',
firstName: 'kim',
lastName: 'seunghyun',
username: 'ashel',
password: '1234', …}
email
:
"cvtcvt007@naver.com"
firstName
:
"kim"
lastName
:
"seunghyun"
password
:
"1234"
password1
:
"1234"
username
:
"ashel"
기존 form에서는 event.preventDefault()
를 이용해 form의 제출을 사용했다.useForm()
에서는 handleSubmit
을 사용한다.
const { register, watch, handleSubmit } = useForm();
handleSubmit
을 통해 출력해보자
function ToDoList() {
//handleSubmit은 form에서 사용된다.
const { register, handleSubmit } = useForm();
//button을 클릭 후 제출 시 onValid 함수가 출력된다.
const onValid = (data: any) => console.log(data);
return (
<div>
//require만 추가해주면 유효성검사가 된다.
<form onSubmit={handleSubmit(onValid)}>
<input {...register("email", { required: true })} placeholder="Email" />
<input
{...register("firstName", { required: true })}
placeholder="First Name"
/>
<input
{...register("lastName", { required: true })}
placeholder="Last Name"
/>
<input
{...register("username", { required: true, minLength: 10 })}
placeholder="Username"
/>
<input
{...register("password", { required: true, minLength: 5 })}
placeholder="Password"
/>
<input
{...register("password1", {
required: "Password is required",
minLength: {
value: 5,
message: "Your password is too short.",
},
})}
placeholder="Password1"
/>
<button>Add</button>
</form>
</div>
);
}
export default ToDoList;
- formState : 전체 양식 상태에 대한 정보가 포함되어 있다. 다양한 옵션들이 있지만 결국 error를 찾기에 적합하다.
import { useState } from "react";
import { useForm } from "react-hook-form";
function ToDoList() {
//formState를 통해 valid되지 않은 데이터들을 출력한다.
const { register, handleSubmit, formState } = useForm();
const onValid = (data: any) => {
console.log(data);
};
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="First Name"
/>
<input
{...register("lastName", { required: true })}
placeholder="Last Name"
/>
<input
{...register("username", { required: true, minLength: 10 })}
placeholder="Username"
/>
<input
{...register("password", { required: true, minLength: 5 })}
placeholder="Password"
/>
<input
{...register("password1", {
required: "Password is required",
minLength: {
value: 5,
message: "Your password is too short.",
},
})}
placeholder="Password1"
/>
<button>Add</button>
</form>
</div>
);
}
export default ToDoList;
여기까지는 formState
를 통해 검사했을 때 error를 콘솔에 출력했다.
email 같은 특정 정규식의 valid를 찾기 위해서는 정규식을 사용한다.
결국 검사는 pattern
, required
를 통해 한다.
- 정규식 사용
<input
{...register("email", {
required: "Email is required",
//pattern 내에 value : 정규식을 추가해주고 , message를 통해 틀렸을 때의 출력을 해준다.
pattern: {
value: /^[A-Za-z0-9._%+-]+@naver.com$/,
message: "Only naver.com emails allowed",
},
})}
placeholder="Email"
/>
이제 사용자 화면에도 틀린 유효성 검사를 출력하자.
기존에 있던 formState.errors
를 삭제하고 formState:{errors}
를 저장하자.
const {
register,
handleSubmit,
formState: { errors },
//생성된 inteface를 넣어준다.
} = useForm<IForm>({
defaultValues: {
email: "@naver.com",
},
});
interface를 생성
interface IForm {
email: string;
firstName: string;
lastName: string;
username: string;
password: string;
password1: string;
}
span
태그 내에 error
를 출력한다.
//다른 항목의 유효성검사도 같은 코드이다.
<span>{errors?.email?.message}</span>
- setError : 특정한 error를 발생시켜준다.
const onValid = (data: IForm) => {
if (data.password !== data.password1) {
//useForm에 있는 setError를 이용한다.
setError(
//password1 은 기존에 register로 저장된 값이다. password로 바꾸면 위에 출력된다.
"password1",
{
//나중에 Error.message를 통해 출력될 값을 넣어준다.
message: "Password are not the same",
},
{ shouldFocus: true }
);
}
};
- shouldFocus :
shouldFocus
를 통해 틀렸을 때 이동시킨다.
const onValid = (data: IForm) => {
if (data.password !== data.password1) {
setError(
"password1",
{ message: "Password are not the same" },
//shouldFocus를 통해 틀리면 이동시킨다.
{ shouldFocus: true }
);
}
};
- validate : 특정 이름이나 단어들을 원하지 않을 때 (또는 포함이 됐을 때 ) 허용시키지 않는다.
회원가입을 할 때 특정 단어나 욕설, 비방 단어들을 관리할 때 사용한다. (게임에서 아이디를 만들 때 "사용할 수 없습니다")
<input
{...register("firstName", {
required: "write here",
validate: {
noPizza: (value) =>
value.includes("pizza") ? "no pizza allowed" : true,
noAdmin: (value) =>
value.includes("admin") ? "no admin allowed" : true,
},
})}
placeholder="First Name"
/>
728x90
반응형
'스터디 > REACT' 카테고리의 다른 글
Recoil & react-hook-from (✈️ travel list) (3) | 2024.03.13 |
---|---|
Recoil (0) | 2024.03.11 |
React 데이터 관리 및 라우팅 (1) | 2024.02.24 |