React 내 Form을 간단하고 효율적으로 관리하도록 도와주는 라이브러리
React Hook Form - performant, flexible and extensible form library
Performant, flexible and extensible forms with easy-to-use validation.
react-hook-form.com
특징
간편한 유효성 검사, 리렌더링 최소화로 빠른성능, Controlled와 Uncontrolled 컴포넌트를 모두 지원, 기존 HTML 폼 활용
* Controlled vs Uncontrolled Components
Controlled Components
- React 상태(useState)를 통해 폼 값을 관리.
- 상태가 업데이트될 때마다 컴포넌트가 리렌더링됨.
- 모든 폼 상태를 React에서 제어.
Uncontrolled Components (React Hook Form 방식)
- HTML 폼 요소의 내장 상태를 그대로 활용.
- 값 변경 시 React의 상태 업데이트가 발생하지 않음.
- 폼 데이터를 필요할 때만 참조(ref 사용).
설치
npm install react-hook-form
주요 함수와 객체
import { useForm } from "react-hook-form";
const { register, handleSubmit, watch, formState: { errors } } = useForm<Type?>();
1. useForm
폼 상태와 유효성 검사 로직을 제공.
반환값 ( register, handleSubmit , watch , formState )
2. register
폼요소 등록.
register("필드명")로 HTML 폼 요소( input, select, textarea..)를 React Hook Form에 연결.
유효성 검사 규칙( 필수 여부, 최소/최대 값, 패턴 )을 설정 가능
ex) required, minLength, maxLength, pattern, validate, disabled
<input {...register('username', { required: true, maxLength: 20 })} />
register("username", { required: "This field is required" });//메세지도 가능
register("email", {
pattern: {
value: /^\S+@\S+$/i,
message: "Please enter a valid email",
},
}); //따로도 가능
* validate
유효성 검사를 위한 함수, 객체 설정
register("password", {
validate: (value) => value.includes("!") || "Password must include a special character (!)",
});
여러규칙도 가능
register("password", {
validate: {
hasNumber: (value) => /\d/.test(value) || "Password must include a number",
hasUppercase: (value) => /[A-Z]/.test(value) || "Password must include an uppercase letter",
},
});
3. handleSubmit
폼 제출될 때 유효성 검사 실행, 콜백 함수 호출
const onSubmit = (data:<Type?>) => {
console.log(data);
};
<form onSubmit={handleSubmit(onSubmit)}>
- errors 존재 시 form 제출x
- 유효성 검사 실패 시 해당 입력 필드 자동 focus 처리
4. watch
폼 필드 값 실시간 관찰
객체 반환, 값이 없으면 undefined, 리렌더링x
const { register, watch } = useForm();
const username = watch("username"); // "username" 필드의 값 관찰
return (
<form>
<input {...register("username")} placeholder="Username" />
<p>현재 입력된 Username: {username}</p>
</form>
);
const [username, email] = watch(["username", "email"]); //여러 필드 값 관찰
const formValues = watch(); // 모든 필드 값 관찰
<p>Form Values: {JSON.stringify(formValues)}</p>
const showEmailField = watch("username") === "admin"; // 조건부 로직
<input {...register("username")} placeholder="Username" />
{showEmailField && <input {...register("email")} placeholder="Email" />}
5. formState
const {
register,
handleSubmit,
formState: { errors, isDirty, isValid, isSubmitting, touchedFields },
} = useForm();
- errors : 유효성 검사 에러 저장
- isDirty : 필드 값 수정되었는지 확인
- isValid : 폼 유효 상태 여부 (모든 필드 유효시 true)
- isSubmitting : 제출 중 상태 나타냄 ( handleSubmit이 호출될 때 true ,끝나면 false)
- isSubmitted : 폼이 한 번이라도 제출되었는지 여부
- touchedFields : 사용자가 상호작용(포커스/블러 등)한 필드 정보를 객체로 제공
- dirtyFields : 값이 변경된 필드 정보를 객체로 제공
- submitCount : 폼이 제출된 횟수
+.setValue
setValue("toDo", "") //("필드명",설정값)
...
<input {...register("toDo")>
사용
const { register, handleSubmit, watch, formState: { errors }} = useForm();
const password = watch("password");
const onsubmit = (data : any) =>{
console.log(data)
}
return(
<form onSubmit={ handleSubmit(onsubmit) }>
<input { ...register("username", { required : true, minLength: 1, maxLength: 15})} placeholder="Username"/><br />
<input
{ ...register('email', { required : "Email is required", pattern: { value: /^\S+@\S+$/i, message: "Invalid email address" }})}
placeholder="email"
/>
<div>{ errors.email?.message as string }</div>
<input type="password"
{ ...register('password', { required : "password is required", minLength : {value : 6, message: "Password must be at least 6"}})}
placeholder="password"
/>
<div>{ errors.password?.message as string }</div>
<input type="password"
{...register("confrimPassword", { validate : (value) => value === password || "Passwords do not match",})}
placeholder="Confirm Password"
/>
<div>{ errors.confrimPassword?.message as string }</div>
<button type="submit">Submit</button>
</form>
);
기본값 설정
interface IUser {
username : string;
email : string;
password : string;
confrimPassword : string;
}
const { register, handleSubmit, watch, formState: { errors }} = useForm<IUser>({
defaultValues : { email: "@gmail.com", }
});
'React' 카테고리의 다른 글
| [React] Framer Motion(1) (0) | 2025.07.02 |
|---|---|
| [React] React-beautiful-dnd (0) | 2025.01.01 |
| [React] Recoil (0) | 2024.12.20 |
| [React] ApexCharts.js (0) | 2024.12.15 |
| [React] React Helmet / Icon (0) | 2024.12.13 |