[React] React Hook Form

2024. 12. 27. 00:34·React

 

React 내 Form을 간단하고 효율적으로 관리하도록 도와주는 라이브러리

 

https://react-hook-form.com/

 

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
'React' 카테고리의 다른 글
  • [React] Framer Motion(1)
  • [React] React-beautiful-dnd
  • [React] Recoil
  • [React] ApexCharts.js
Naah
Naah
  • Naah
    blueprint
    Naah
  • 전체
    오늘
    어제
    • 분류 전체보기 (106)
      • Java (28)
      • Kotlin (0)
      • TypeScript (7)
      • React (22)
      • Next.js (1)
      • Spring (22)
      • JPA (12)
      • Spring Data JPA (6)
      • Querydsl (1)
      • Error (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • manage
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Naah
[React] React Hook Form
상단으로

티스토리툴바