icon안동민 개발노트

useForm 훅 소개


 react-hook-form 라이브러리의 useForm 훅은 React 애플리케이션에서 폼 관리를 더욱 효율적이고 간편하게 만들어줍니다.

 이 훅은 폼 상태 관리, 유효성 검사, 에러 처리 등을 쉽게 구현할 수 있게 해주며, 성능 최적화에도 도움을 줍니다.

useForm 훅의 기본 사용법

 먼저 react-hook-form을 설치합니다.

npm install react-hook-form

 그리고 다음과 같이 사용할 수 있습니다.

import React from 'react';
import { useForm } from 'react-hook-form';
 
function SimpleForm() {
  const { register, handleSubmit, formState: { errors } } = useForm();
 
  const onSubmit = (data) => console.log(data);
 
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name", { required: "Name is required" })} />
      {errors.name && <span>{errors.name.message}</span>}
      
      <input {...register("email", { 
        required: "Email is required",
        pattern: {
          value: /^\S+@\S+$/i,
          message: "Invalid email format"
        }
      })} />
      {errors.email && <span>{errors.email.message}</span>}
      
      <button type="submit">Submit</button>
    </form>
  );
}

 이 예제에서,

  • register 함수는 입력 필드를 등록하고 유효성 검사 규칙을 설정합니다.
  • handleSubmit은 폼 제출을 처리합니다.
  • errors 객체는 유효성 검사 오류를 포함합니다.

폼 필드 등록과 유효성 검사 규칙 설정

 useForm 훅을 사용하면 다양한 유효성 검사 규칙을 쉽게 설정할 수 있습니다.

<input {...register("age", { 
  required: "Age is required",
  min: { value: 18, message: "Must be at least 18" },
  max: { value: 99, message: "Must be 99 or younger" }
})} />

에러 처리

 errors 객체를 사용하여 각 필드의 에러를 쉽게 처리할 수 있습니다.

{errors.age && <span className="error">{errors.age.message}</span>}

폼 제출 처리

 handleSubmit 함수를 사용하여 폼 제출을 처리합니다.

const onSubmit = async (data) => {
  try {
    const response = await api.submitForm(data);
    console.log('Form submitted successfully', response);
  } catch (error) {
    console.error('Error submitting form', error);
  }
};
 
return <form onSubmit={handleSubmit(onSubmit)}>...</form>;

react-hook-form의 장점

  1. 성능 최적화 : 불필요한 리렌더링을 최소화하여 성능을 향상시킵니다.
  2. 간결한 코드 : 복잡한 폼 로직을 간단하게 구현할 수 있습니다.
  3. 유연성 : 다양한 유효성 검사 규칙과 커스텀 로직을 쉽게 적용할 수 있습니다.
  4. 타입스크립트 지원 : 타입 안정성을 제공합니다.

성능 최적화 방법

 react-hook-form은 기본적으로 성능에 최적화되어 있지만, 다음과 같은 방법으로 더욱 성능을 향상시킬 수 있습니다.

  1. Controller 컴포넌트 사용 : 제어 컴포넌트를 최적화하기 위해 Controller를 사용합니다.
import { Controller } from 'react-hook-form';
 
<Controller
  name="select"
  control={control}
  render={({ field }) => <Select {...field} />}
/>
  1. watch 함수의 선별적 사용 : 필요한 필드만 watch하여 불필요한 리렌더링을 방지합니다.
const watchedValue = watch("fieldName");

기존 폼 관리 방식과의 차이점

  1. 상태 관리 간소화 : useState로 각 필드의 상태를 관리할 필요가 없습니다.
  2. 자동 유효성 검사 : 복잡한 유효성 검사 로직을 간단하게 구현할 수 있습니다.
  3. 성능 : 불필요한 리렌더링을 자동으로 최적화합니다.
  4. 에러 처리 : 에러 상태를 쉽게 관리하고 표시할 수 있습니다.

복잡한 폼 시나리오에서의 useForm 활용

 1. 동적 폼 필드

const { fields, append, remove } = useFieldArray({
  control,
  name: "items"
});
 
return (
  <form onSubmit={handleSubmit(onSubmit)}>
    {fields.map((field, index) => (
      <div key={field.id}>
        <input {...register(`items.${index}.name`)} />
        <button type="button" onClick={() => remove(index)}>Delete</button>
      </div>
    ))}
    <button type="button" onClick={() => append({ name: '' })}>Add Item</button>
    <button type="submit">Submit</button>
  </form>
);

 2. 조건부 유효성 검사

const { register, watch } = useForm();
const watchShowAge = watch("showAge", false);
 
return (
  <form>
    <input type="checkbox" {...register("showAge")} />
    {watchShowAge && (
      <input {...register("age", { required: "Age is required" })} />
    )}
  </form>
);

 3. 비동기 유효성 검사

const { register } = useForm();
 
return (
  <input {...register("username", {
    validate: async value => {
      const response = await fetch(`/api/check-username?username=${value}`);
      const result = await response.json();
      return result.isAvailable || "Username is already taken";
    }
  })} />
);

 4. 폼 상태 재설정

const { reset } = useForm();
 
const handleReset = () => {
  reset({
    name: '',
    email: '',
    // ... 다른 필드들
  });
};

 5. 서버 사이드 에러 처리

const { setError } = useForm();
 
const onSubmit = async (data) => {
  try {
    await submitForm(data);
  } catch (error) {
    setError("root.serverError", {
      type: "server",
      message: "An error occurred while submitting the form"
    });
  }
};

 react-hook-form의 useForm 훅은 React 애플리케이션에서 폼 관리를 크게 간소화합니다. 이 라이브러리는 복잡한 폼 로직을 쉽게 구현할 수 있게 해주며, 동시에 성능도 최적화합니다. 기존의 폼 관리 방식에 비해 코드량을 줄이고 가독성을 높이며, 다양한 폼 시나리오에 유연하게 대응할 수 있습니다.

 특히 대규모 애플리케이션이나 복잡한 폼을 다루는 경우, useForm의 이점이 더욱 두드러집니다. 동적 폼 필드, 조건부 유효성 검사, 비동기 검증 등 고급 기능들을 손쉽게 구현할 수 있어, 개발자의 생산성을 크게 향상시킵니다.

 그러나 모든 상황에 react-hook-form이 필요한 것은 아닙니다. 간단한 폼의 경우 기본적인 React 상태 관리만으로도 충분할 수 있습니다. 따라서 프로젝트의 복잡성과 요구사항을 고려하여 적절한 도구를 선택하는 것이 중요합니다.