개발 공부 일지/React

[React] React Hook Form 라이브러리로 Form 간편하게 관리하기

dev-hpk 2024. 11. 27. 15:58

React 애플리케이션에서 폼 관리는 매우 빈번한 작업입니다. React State를 이용해 폼 상태를 관리하고, 유효성을 검증하며, 성능을 최적화하는 것은 번거로울 수 있습니다. React Hook Form은 이러한 작업을 간소화하고 성능을 최적화해 주는 가볍고 직관적인 폼 관리 라이브러리입니다.

목차

1. React Hook Form이란?

2. React Hook Form 설치 및 기본 사용법

3. 주요 Hook과 함수

4. React Form vs React Hook Form

추천글

위의 목차를 클릭하면 해당 글로 자동 이동 합니다.

 

1. React Hook Form이란?

React Hook Form은 React의 Hooks API를 기반으로 설계된 폼 관리 라이브러리입니다. HTML의 기본 폼 요소를 활용해 최소한의 리렌더링으로 효율적인 폼 관리를 가능하게 합니다. 특히 다음과 같은 장점이 있습니다.

  • 간소화된 코드: 기본적으로 제공하는 Hook 함수들과 컴포넌트들을 사용하여 폼을 쉽게 생성하고 관리할 수 있습니다.
  • 최소한의 리렌더링: 입력 필드의 값 변화를 추적하는 "상태" 대신 각 입력 필드의 참조(reference)를 사용하여 불필요한 리렌더링을 방지하고, 가상 DOM의 업데이트를 최소화합니다.
  • 유효성 검사: 기본 HTML의 유효성 검사 속성(required, pattern 등)을 지원해 유효성 검사를 쉽게 설정할 수 있습니다. 외부 라이브러리와 통합하여 커스텀 검증도 가능합니다.

2. React Hook Form 설치 및 기본 사용법

설치

 

 

Get Started

Performant, flexible and extensible forms with easy-to-use validation.

www.react-hook-form.com

// npm
npm install react-hook-form

// yarn
yarn add react-hook-form

 

기본 사용법

React Hook Form을 사용하여 간단한 로그인 폼을 작성해 보겠습니다.

import { useForm } from 'react-hook-form';

export default function LoginForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => {
    console.log(data); // 입력 데이터를 출력
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>이메일</label>
        <input
          {...register('email', { required: '이메일을 입력해주세요.', pattern: /^\S+@\S+$/i })}
        />
        {errors.email && <p>{errors.email.message}</p>}
      </div>
      <div>
        <label>비밀번호</label>
        <input
          type="password"
          {...register('password', { required: '비밀번호를 입력해주세요.', minLength: 6 })}
        />
        {errors.password && <p>{errors.password.message}</p>}
      </div>
      <button type="submit">로그인</button>
    </form>
  );
}

 

3. 주요 Hook과 함수

useForm

React Hook Form의 핵심 함수로, 폼의 인스턴스를 생성하고 폼 상태와 동작을 관리하는 기본 Hook입니다.

const {
  register,
  handleSubmit,
  watch,
  formState: { errors },
} = useForm();

 

register

입력 필드를 React Hook Form에 등록합니다. 입력 필드에 대한 유효성 검사 규칙, 기본값 등을 설정할 수 있습니다.

<input
  {...register('id', { required: '아이디를 입력해주세요.', maxLength: 10 })}
/>

handleSubmit

폼 제출 시 실행할 함수를 정의합니다. 이 함수는 유효성 검사를 수행하고, 제출할 데이터를 처리하는 로직을 작성할 수 있습니다. 

<form onSubmit={handleSubmit(onSubmit)}>
  ...
</form>

 

watch

특정 입력 필드의 상태를 실시간으로 관찰합니다.

formState.errors

폼 상태와 관련된 다양한 정보를 제공합니다.

formState: {
  errors,   // 유효성 검사 에러
  isSubmitting, // 제출 중 여부
  isDirty,  // 입력 필드 변경 여부
  isValid,  // 폼 전체 유효성
}

 

 

4. React Form vs React Hook Form 💥

React Form: State를 이용한 Form 관리

import { useState } from 'react';

function Form() {
  const [formData, setFormData] = useState({
    email: '',
    password: '',
  });

  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  };

  const validate = () => {
    const newErrors = {};
    if (!formData.email) {
      newErrors.email = '이메일을 입력해주세요.';
    } else if (!/^\S+@\S+$/.test(formData.email)) {
      newErrors.email = '사용할 수 없는 이메일 형식입니다.';
    }
    if (!formData.password) {
      newErrors.password = '비밀번호를 입력해주세요.';
    } else if (formData.password.length < 6) {
      newErrors.password = '비밀번호는 6자 이상입니다.';
    }
    return newErrors;
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const validationErrors = validate();
    if (Object.keys(validationErrors).length > 0) {
      setErrors(validationErrors);
    } else {
      console.log(formData);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>이메일</label>
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
        />
        {errors.email && <p>{errors.email}</p>}
      </div>
      <div>
        <label>비밀번호</label>
        <input
          type="password"
          name="password"
          value={formData.password}
          onChange={handleChange}
        />
        {errors.password && <p>{errors.password}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;

 

  • 복잡한 코드: 입력 필드마다 상태를 관리하고, 검증 로직을 수동으로 작성해야 합니다.
  • 유효성 검사 코드 중복: 필드별 검증 로직이 중복되기 쉽습니다.
  • 성능 문제: 모든 입력이 변경될 때마다 상태가 업데이트되어 불필요한 리렌더링이 발생할 수 있습니다.

React Hook Form

import { useForm } from 'react-hook-form';

function Form() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>이메일</label>
        <input
          type="email"
          {...register('email', {
            required: '이메일을 입력해주세요.',
            pattern: { value: /^\S+@\S+$/, message: '사용할 수 없는 이메일 형식입니다.' },
          })}
        />
        {errors.email && <p>{errors.email.message}</p>}
      </div>
      <div>
        <label>비밀번호</label>
        <input
          type="password"
          {...register('password', {
            required: '비밀번호를 입력해주세요.',
            minLength: { value: 6, message: '비밀번호는 6자 이상입니다.' },
          })}
        />
        {errors.password && <p>{errors.password.message}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;

 

React Form과 비교해 보면, React Hook Form은 상태 관리와 유효성 검사를 훨씬 간단히 처리합니다.

 

비교 항목 React Form(state 기반 관리) React Hook Form
코드 길이 입력 필드와 유효성 검사 코드가 길고 반복적입니다. 간결한 코드로 입력 필드와 유효성 검사를 쉽게 관리할 수 있습니다.
유효성 검사 별도로 검증 함수 작성 및 상태 업데이트가 필요합니다. register와 검증 규칙을 선언적으로 정의할 수 있어 가독성이 높습니다.
성능 상태 업데이트와 리렌더링이 모든 입력 필드에 영향을 줄 수 있습니다. 입력 필드별로 상태를 독립적으로 관리하여 불필요한 리렌더링을 방지합니다.
개발 생산성 상태 관리와 검증 로직을 수동으로 작성해야 하므로 유지보수와 확장이 어렵습니다. 선언적인 API와 간단한 통합으로 폼 로직 작성 시간을 줄이고 확장이 쉽습니다.

 

 

React로 폼을 작성하는 시간을 줄이고, 간결하면서도 성능이 뛰어난 폼 관리 경험을 원한다면, React Hook Form을 적극 추천합니다👍👍

 

 

추천글

 

[React] Compound Component Pattern

React로 컴포넌트를 만들다 보면 디자인이 바뀌어 컴포넌트를 재사용할 수 없거나, 처음 계획가 달리 컴포넌트의 구조가 복잡해지는 경우가 있습니다. 이로 인해 코드의 가독성이 떨어지거나 새

dev-hpk.tistory.com

 

 

[React] Render Props Pattern

구성 요소를 재사용 가능하게 만드는 방법은 render prop 패턴을 사용하는 것입니다. render prop은 JSX 요소를 반환하는 함수입니다. 컴포넌트 자체는 render prop 외에는 아무것도 렌더링 하지 않습니

dev-hpk.tistory.com