
들어가며
React Hook Form 은 비제어 컴포넌트를 기반으로 동작하는 폼 관리 라이브러리다.
React 에서 form 을 쉽게 관리할 수 있도록 해주며, form의 상태 관리와 유효성 검사를 간단하게 만들어준다.
React Hook Form
React Hook Form 은 다음의 커맨드로 설치할 수 있다.
npm install react-hook-form
React Hook Form 은 useForm 이라는 훅을 통해 폼 상태, 검증 및 제출 로직을 관리한다.
import { useForm } from 'react-hook-form'
React Hook Form 에서 주로 사용되는 메서드는 아래와 같다.
- register : 입력 요소에 연결하기 위한 함수. 이 함수를 통해서 입력 요소에 유효성 검사 규칙을 설정할 수 있다
- handleSubmit : 폼의 제출을 처리하기 위한 함수. 이 함수에 전달된 콜백은 유효성 검사를 통과한 데이터를 인자로 받아서 실행한다.
- watch : 특정 폼 필드의 값을 실시간으로 관찰하는 함수
- formState : 폼의 상태를 나타내는 객체 (ex. errors, isValid, isDirty, isSubmitted 등의 상태 포함)
예시 코드
import React from "react";
import { useForm } from "react-hook-form";
const errorMsgStyle = {
fontSize: "12px",
color: "red",
};
export default function Form() {
const {
register, // input 할당, value 변경 감지
handleSubmit, // form submit 시 호출
formState: { errors }, // 폼 상태 객체
watch, // 특정 폼 필드의 값을 실시간으로 사용
} = useForm();
// handleSubmit(func A[, func B]) - 두개의 함수를 인자로 받는다. (두번째인자는 생략 가능)
// func A는 필수 값, 유효할 때 실행
// func B는 선택, 유효하지 않을 때 실행
// func A -> 유효할 떄 실행
const onValid = (data) => {
console.log("onValid >>> ", data);
};
// func B -> 유효하지 않을 때 실행
const onInValid = (err) => {
console.log("onInValid >>> ", err);
};
console.log("errors>>>", errors);
console.log("watch>>>", watch("username"));
return (
<div>
<h1>react-hook-form 라이브러리 DEMO</h1>
<form onSubmit={handleSubmit(onValid, onInValid)}>
<div>
<input
type="text"
placeholder="username"
{...register("username", {
required: "이름은 필수항목입니다.",
minLength: {
message: "이름은 최소 2글자 이상 작성해주세요",
value: 2,
},
})}
// 'username'이라는 필드명 / required, minLengh 라는 유효성 검사 규칙
// 'username' 이라는 input 필드를 RHF(react-hook-form)에 등록
/>
{errors.username && (
<div style={errorMsgStyle}>{errors.username.message}</div>
)}
</div>
{/* 이 표현은 조건부 렌더링과 옵셔널 체이닝을 활용하여 폼 필드의 오류 메시지를 표시하는 방법 */}
{/* errors = formState 객체 중 하나 각 폼 필드에 대한 오류 메시지를 담고, 유효성 검사가 실패한 경우에만 해당 필드의 오류 메시지가 저장됨 */}
{/* 옵셔널 체이닝 연산자 '?.'
JS에서 객체의 속성에 접근할 때 해당 속성이 존재하는지 확인하고, 없을 경우 undefined 반환하는 연산자 */}
<div>
<input
type="email"
placeholder="email(gmail)"
{...register("email", {
required: "이메일을 입력해주세요",
validate: {
useGmail: (v) =>
v.includes("gmail.com") || "gmail로만 가입 가능합니다.",
},
})}
/>
{/* validate : reat hook form 에서 제공하는 유효성 검사 옵션 중 하나,
폼 필드에 대하 커스텀 유효성 검사를 수행할 수 있도록 함,
함수 또는 함수들을 포함하는 객체를 받을 수 있음 */}
{/* validate 가 객체로 사용될 경우, 객체의 각 속성에 대해 개별적인 유효성 검사 수행 가능
각 속성은 함수 형태로 정의, 이 함수들이 개별적인 유효성 검사 규칙 적용 */}
{/*
useGmail : validate 옵션의 객체 내부에서 useGmail 이라는 이름의 함수로 정의, 특정 유효성 검사 규칙 설정
v : 사용자가 email 필드에 입력한 값(이메일 주소)을 의미
*/}
{errors.email && (
<div style={errorMsgStyle}>{errors.email.message}</div>
)}
</div>
<div>
<input
type="password"
placeholder="password"
{...register("password", {
required: "비밀번호를 입력해주세요",
pattern: {
value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{2,8}$/,
message: "2~8글자의 영어+숫자 조합으로 입력해주세요",
},
})}
/>
{/* pattern 을 사용해서 정규식으로 유효성 검사 가능 */}
{errors.password && (
<div style={errorMsgStyle}>{errors.password.message}</div>
)}
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
결과


React Hook Form 의 특징
React Hook Form 은 비제어 컴포넌트 기반으로 동작하기 때문에
폼 필드가 업데이트 될 때마다 전체 폼이 리렌더링 되지는 않는다.
이로 인해 불필요한 렌더링을 줄이고, 결과적으론 앱성능을 향상시킬 수 있다.
즉, 최적화에 적합하다.
또한, HTML5 의 기본적인 검증 속성인 required, minLength, maxLength 등을 사용할 수 있어,
검증 로직을 쉽고 간편하게 구현할 수 있다.
또, error 등 상태를 나타낼 수 있는 객체를 사용해서 간단하게 에러 메시지를 관리할 수 있다.
React Hook Form 의 동작 방식
앞서, React Hook Form 은 비제어 컴포넌트 기반으로 동작한다고 했다.
그래서 input 이나 form 의 값을 react state 에서 직접 관리하는 것이 아니라, 브라우저의 DOM 상태를 참조한다.
이로 인해 최소한의 리렌더링을 하여 성능을 향상 시킬 수 있다.
register 함수가 input 요소를 등록해서 DOM 참조를 생성하고, 이를 통해 값을 관리한다.
상태 관리는 폼 제출, 유효성 검사 시점에서 이루어진다.
React Hook Form 과 일반 Form 작성 비교
일반 Form
- 각 입력 필드의 상태를 useState 로 관리해야함
- 값이 바뀔 때마다 전체 컴포넌트가 리렌더링 될 수 있다.
- 검증 로직을 직접 다 작성해야한다.
- 폼 제출 시 각 입력 필드의 상태들을 모아서 폼 데이터를 수집해야 한다.
React Hook Form
- useForm이라는 단일 훅을 이용해서 폼 상태, 검증 및 제출 로직을 관리하므로, 사용법이 직관적이고 코드가 간결하다.
- 비제어 컴포넌트 기반으로 동작하여 필요한 경우에만 리렌더링 한다.
- 다양한 검증 규칙을 쉽게 설정할 수 있다
- handleSubmit 함수 하나로 모든 폼 데이터를 쉽게 관리할 수 있다.
이를 표로 정리하면 다음과 같다.
| 특징 | 일반 Form | React Hook Form |
| 상태 관리 | React State 로 직접 관리 | 비제어 컴포넌트를 사용하여 상태를 DOM 에서 관리 |
| 유효성 검사 | 별도의 검증 로직을 작성 | register 등을 사용해서 간단하게 구현 가능 |
| 리렌더링 | 입력값 변경 시마다 리렌더링 발생 | 비제어 컴포넌트 기반으로 리렌더링 최소화 |
| 코드 복잡도 | state 관리 및 이벤트 핸들러로 인해 코드가 길어질 수 있음 | 간결한 코드로 작성 가능 |
| 성능 | 대규모 폼 양식 작성 시 성능 저하 문제 발생할 수 있음 | 최소한의 리렌더링으로 인한 성능 향상 |
따라서 일반 Form 양식은 간단한 폼 양식 작성 시에 사용하기 적합하고
React Hook Form 복잡하고 대규모 폼 양식을 작성할 떄 사용하기 적합하다.
(ex. 회원가입/로그인 폼 등)
따라서 리액트 프로젝트에서 form 을 사용할 일이 있으면
프로젝트의 규모, form 을 사용하는 곳의 규모를 생각해서 적절한 것을 사용하면 되겠다.
Reference
코딩온 교안 자료
'Study > React' 카테고리의 다른 글
| [React] React Datepicker 이용해서 달력 만들기 (1) | 2024.12.03 |
|---|---|
| [React] React의 렌더링 프로세스(Virtual DOM) (1) | 2024.11.26 |
| [React] 제어 컴포넌트와 비제어 컴포넌트 (1) | 2024.11.22 |
| [React] Zustand 로 상태 관리 해보기 (0) | 2024.11.16 |
| [React] React Query 로 무한스크롤 구현 (1) | 2024.11.13 |