react hook form 사용하기

React Hook Form

폼을 쉽게 만들고 유효성 검사를 수행할 수 있도록 도와주는 라이브러리

 

성능이 좋고, 비제어 컴포넌트를 사용하며(제어 방식도 지원하는 듯), 소스코드가 깔끔하다.

 

더보기
더보기
더보기

제어 컴포넌트 -> 사용자가 입력한 값이 state로 실시간 동기화됨. 데이터 검증에 유리하지만, 많은 리렌더링 발생 가능성도 높음

 

비제어 컴포넌트 -> 입력이 모두 끝난 후에 ref를 통해 값을 한번에 가져옴. 성능이 좋지만, 데이터 검증이 어려움

 

설치 방법

npm install react-hook-form
yarn add react-hook-form

 

기본 로그인 폼

<form>
      <label htmlFor="email">이메일</label>
      <input id="email" type="email" placeholder="test@email.com" />
      <label htmlFor="password">비밀번호</label>
      <input id="password" type="password" placeholder="****************" />
      <button type="submit">로그인</button>
    </form>
  );
}

여기에 리액트 훅 폼을 연결하면

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

function LoginForm() {
  const { register, handleSubmit } = useForm();

  return (
    <form onSubmit={handleSubmit((data) => alert(JSON.stringify(data)))}>
      <label htmlFor="email">이메일</label>
      <input
        id="email"
        type="email"
        placeholder="test@email.com"
        {...register("email")} // 추가
      />
      <label htmlFor="password">비밀번호</label>
      <input
        id="password"
        type="password"
        placeholder="****************"
        {...register("password")} // 추가
      />
      <button type="submit">로그인</button>
    </form>
  );
}

export default LoginForm;

이렇게 된다.

로그인 버튼을 클릭하면 입력한 내용이 alert로 나타남!!

 

 

 

기본 사용법

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

const {
  handleSubmit, // form의 onSubmit에 사용하는 함수
  register, // 이벤트 객체 생성
  watch, // 모든 값을 확인하는 함수
  formState: { errors }, // 에러 메시지 관리
} = useForm();

 

주요 개념

1. useForm

= 폼을 관리하는 데 필요한 기능들을 제공

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

const { register, handleSubmit } = useForm();

 

2. register

= 폼의 각 입력 필드를 등록하고 유효성 검사를 설정

인풋 요소를 등록하는 데 사용

함수의 두번째 파라미터를 사용해 유효성 검증 가능

import { useForm } from 'react-hook-form';  // react-hook-form 라이브러리에서 useForm 훅을 가져옵니다.

export default function App() {
  const { register } = useForm();  // useForm 훅을 사용해서 register 함수를 얻습니다.
  return <input {...register('firstName')} />;  // input 요소에 register 함수를 사용하여 'firstName'이라는 이름을 등록합니다.
}

이 input 요소가 firstName이라는 이름으로 폼에 등록되게 함

간단한 등록 방법임

 

* 또 다른 코드

import { useForm } from 'react-hook-form';  // react-hook-form 라이브러리에서 useForm 훅을 가져옵니다.

export default function App() {
  const { register } = useForm();  // useForm 훅을 사용해서 register 함수를 얻습니다.
  const { onChange, onBlur, name, ref } = register('firstName');  // register 함수로 여러 가지 속성들을 얻습니다.

  return (
    <input
      onChange={onChange}  // input 값이 변경될 때 호출되는 함수
      onBlur={onBlur}  // input이 포커스를 잃을 때 호출되는 함수
      name={name}  // input의 이름, 여기서는 'firstName'
      ref={ref}  // input 요소를 참조하는 ref
    />
  )
}

직접 속성을 할당하는 방법임

각 속성을 개별적으로 제어할 수 있음

 

 

3. handleSubmit

= 폼이 제출될 때 실행될 함수를 정의함

유효성 검증을 통과한 사용자 입력 값을 전달받기 위한 함수임

 

4. errors

{errors?.email && <S.ErrMsg>{errors?.email?.message}</S.ErrMsg>}

 


유효성 검증

= register 함수의 두 번째 파라미터인 registerOptions를 사용하면 유효성 검증 가능

// React Hook Form과 SubmitHandler를 임포트합니다.
import { useForm, SubmitHandler } from "react-hook-form";

// 폼 입력값의 타입을 정의하는 인터페이스를 선언합니다.
interface IFormInput {
  firstName: string;
  lastName: string;
  age: number;
}

// 기본 컴포넌트 함수를 정의합니다.
export default function App() {
  // useForm 훅을 호출하여 폼 관련 메서드와 변수를 가져옵니다.
  // 여기서는 IFormInput 인터페이스를 타입으로 사용합니다.
  const { register, handleSubmit } = useForm<IFormInput>();

  // 폼이 제출될 때 호출되는 함수입니다.
  // data 매개변수는 폼 입력값을 포함합니다.
  const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data);

  // 컴포넌트의 JSX 반환값입니다.
  return (
    // 폼 요소를 정의합니다.
    // handleSubmit 함수는 폼 제출을 처리하고, 유효성 검사를 실행합니다.
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 이름 입력 필드입니다. */}
      {/* register 함수는 입력 필드를 폼에 등록하고, 유효성 검사를 설정합니다. */}
      <input {...register("firstName", { required: true, maxLength: 20 })} />
      
      {/* 성 입력 필드입니다. */}
      {/* 패턴을 사용하여 알파벳 문자만 허용합니다. */}
      <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
      
      {/* 나이 입력 필드입니다. */}
      {/* 최소값과 최대값을 설정합니다. */}
      <input type="number" {...register("age", { min: 18, max: 99 })} />
      
      {/* 제출 버튼입니다. */}
      <input type="submit" />
    </form>
  );
}

 

정리

<input {...register("firstName", { required: true, maxLength: 20 })} />
// required: true -> 필수 입력 값임을 나타냄
// maxLength: 20 -> 필드의 최대 길이 제한
(문자열)
<input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
// pattern: /^[A-Za-z]+$/i (정규 표현식 사용)
-> ^ -> 문자열의 시작 의미
-> [A-Za-z] -> 대문자, 소문자 (a-z)로 이루어진 문자 집합 의미
-> + -> 하나 이상의 문자가 포함되어야 함을 의미
-> $ -> 문자열의 끝을 의미
-> /i -> 대소문자를 구분하지 않는다는 옵션
<input type="number" {...register("age", { min: 18, max: 99 })} />
min -> 최소 값
max -> 최대 값
(정수, 소수)
<input
  {...register("firstName", {
    required: true,
    maxLength: 20,
    setValueAs: (value) => value.trim()
  })}
/>

// setValueAs: (value) => value.trim() -> 공백 제거
더보기
더보기
더보기

그 외 정규식

 

이메일

이메일 검증 정규식
정규식: /^\S+@\S+\.\S+$/

^: 문자열의 시작을 나타냅니다.
\S+: 공백이 아닌 문자 하나 이상을 나타냅니다. 여기서 \S는 공백이 아닌 모든 문자를 의미하며, +는 하나 이상을 의미합니다.
@: 이메일 주소에서 사용하는 @ 문자를 나타냅니다.
\S+: 다시 공백이 아닌 문자 하나 이상을 나타냅니다.
.: .(점) 문자를 나타냅니다. 여기서 .는 일반적으로 모든 문자를 의미하지만, \를 붙여서 문자 그대로의 점을 의미합니다.
\S+: 마지막으로 공백이 아닌 문자 하나 이상을 나타냅니다.
$: 문자열의 끝을 나타냅니다.

=이 정규식은 공백이 아닌 문자로 시작해서 @ 문자가 나오고, 그 뒤에 공백이 아닌 문자가 나오고, 점(.)이 하나 있고, 그 뒤에 다시 공백이 아닌 문자가 나오는 형식을 의미합니다.

 

비밀번호

비밀번호 검증 정규식
정규식: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/

^: 문자열의 시작을 나타냅니다.
(?=.*[a-z]): 소문자 알파벳이 적어도 하나는 포함되어야 함을 의미합니다. 여기서 (?=.*[a-z])는 앞으로 소문자 알파벳이 하나 이상 나와야 한다는 뜻입니다.
(?=.*[A-Z]): 대문자 알파벳이 적어도 하나는 포함되어야 함을 의미합니다.
(?=.*\d): 숫자가 적어도 하나는 포함되어야 함을 의미합니다. 여기서 \d는 숫자를 의미합니다.
(?=.[@$!%?&]): 특수문자(@, $, !, %, *, ?, &) 중 적어도 하나는 포함되어야 함을 의미합니다.
[A-Za-z\d@$!%*?&]: 소문자, 대문자 알파벳, 숫자, 특수문자(@, $, !, %, *, ?, &)의 집합을 의미합니다. 이 집합 내의 문자들만 허용됩니다.
{8,}: 앞의 집합이 8개 이상 포함되어야 함을 의미합니다.
$: 문자열의 끝을 나타냅니다.

해석:
이 정규식은 비밀번호가 다음 조건들을 만족해야 함을 나타냅니다:

적어도 하나의 소문자 알파벳(a-z)
적어도 하나의 대문자 알파벳(A-Z)
적어도 하나의 숫자(0-9)
적어도 하나의 특수문자(@, $, !, %, *, ?, &)
최소 8자 이상

 

더보기
더보기
더보기

 

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

function LoginForm({
  onSubmit = async (data) => {
    await new Promise((r) => setTimeout(r, 1000));
    alert(JSON.stringify(data));
  },
}) {
  const {
    register,
    handleSubmit,
    formState: { isSubmitting, isSubmitted, errors },
  } = useForm();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="email">이메일</label>
      <input
        id="email"
        type="text"
        placeholder="test@email.com"
        aria-invalid={isSubmitted ? (errors.email ? "true" : "false") : undefined}
        {...register("email", {
          required: "이메일은 필수 입력입니다.",
          pattern: {
            value: /\S+@\S+\.\S+/,
            message: "이메일 형식에 맞지 않습니다.",
          },
        })}
      />
      {errors.email && <small role="alert">{errors.email.message}</small>}

      <label htmlFor="password">비밀번호</label>
      <input
        id="password"
        type="password"
        placeholder="****************"
        aria-invalid={isSubmitted ? (errors.password ? "true" : "false") : undefined}
        {...register("password", {
          required: "비밀번호는 필수 입력입니다.",
          minLength: {
            value: 8,
            message: "8자리 이상 비밀번호를 사용하세요.",
          },
        })}
      />
      {errors.password && <small role="alert">{errors.password.message}</small>}

      <button type="submit" disabled={isSubmitting}>로그인</button>
    </form>
  );
}

export default LoginForm;

복잡한 폼이나 추가적인 상태 관리가 필요한 경우

에러 메세지

= 유효성 검증에서 잡아낸 에러를 화면에 노출시키기

useForm 훅의 formState.errors 필드를 사용하면 에러 메세지를 화면에 노출할 수 있음

import { useForm, SubmitHandler } from "react-hook-form";

interface IFormInput {
  firstName: string;
  lastName: string;
  age: number;
}

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<IFormInput>();  // useForm 훅을 사용하여 폼 관리 기능을 초기화합니다. 제네릭 타입으로 IFormInput을 지정하여 입력 데이터의 타입을 정의합니다.
  const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data);  // 폼 제출 시 호출될 함수를 정의합니다. 제출된 데이터를 콘솔에 출력합니다.

  return (
    <form onSubmit={handleSubmit(onSubmit)}>  // 폼 요소를 정의합니다. handleSubmit 함수로 폼 제출 이벤트를 처리합니다.
      <input
        {...register("firstName", {  // "firstName" 필드를 등록하고 유효성 검사를 설정합니다.
          required: "필수값 입니다.",  // 필수 입력 값으로 설정하고, 에러 메시지를 지정합니다.
          maxLength: {
            value: 20,  // 최대 길이를 20자로 설정합니다.
            message: "최대 20자를 넘을 수 없습니다."  // 최대 길이를 초과했을 때의 에러 메시지를 지정합니다.
          }
        })}
      />
      {errors.firstName && <span>{errors.firstName.message}</span>}  // firstName 필드에 에러가 있을 경우 에러 메시지를 표시합니다.
      <input
        {...register("lastName", {  // "lastName" 필드를 등록하고 유효성 검사를 설정합니다.
          pattern: {
            value: /^[A-Za-z]+$/i,  // 알파벳 문자만 허용하는 정규식을 사용합니다.
            message: "알파벳만 가능합니다."  // 정규식에 맞지 않을 때의 에러 메시지를 지정합니다.
          }
        })}
      />
      {errors.lastName && <span>{errors.lastName.message}</span>}  // lastName 필드에 에러가 있을 경우 에러 메시지를 표시합니다.
      <input
        type="number"
        {...register("age", {  // "age" 필드를 등록하고 유효성 검사를 설정합니다.
          min: { value: 18, message: "18 미만의 값을 입력할 수 없습니다." },  // 최소 값을 18로 설정하고, 에러 메시지를 지정합니다.
          max: { value: 99, message: "99 초과의 값을 입력할 수 없습니다." }  // 최대 값을 99로 설정하고, 에러 메시지를 지정합니다.
        })}
      />
      {errors.age && <span>{errors.age.message}</span>}  // age 필드에 에러가 있을 경우 에러 메시지를 표시합니다.
      <input type="submit" />  // 폼 제출 버튼을 정의합니다.
    </form>
  );
}

 

* 종속성 있는 유효성 검증 (ex. 비밀번호 입력 태그, 비밀번호 확인 태그 2개가 있다던지...)

watch를 사용하면 값이 업데이트 된 것을 감시할 수 있는데 useWatch라는 것과 성능 측면에서 차이가 있다고 함

watch는 폼의 입력 값이 변경될 때마다 모든 폼 컴포넌트를 리렌더링하고, useWatch는 단위 컴포넌트 내에서만 리렌더링하므로 성능은 useWatch가 더 좋음

// React Hook Form과 SubmitHandler, useWatch를 임포트합니다.
import { useForm, SubmitHandler, useWatch } from "react-hook-form";

// 폼 입력값의 타입을 정의하는 인터페이스를 선언합니다.
interface FormInput {
  password: string;
  passwordConfirm: string;
}

export default function App() {
  // useForm 훅을 호출하여 폼 관련 메서드와 변수를 가져옵니다.
  // 여기서는 FormInput 인터페이스를 타입으로 사용합니다.
  const {
    register,  // 입력 필드를 폼에 등록하기 위한 함수입니다.
    handleSubmit,  // 폼 제출을 처리하고, 유효성 검사를 실행하는 함수입니다.
    control,  // useWatch 훅을 사용하기 위해 필요한 객체입니다.
    formState: { errors }  // 폼의 유효성 검사 에러 정보를 포함합니다.
  } = useForm<FormInput>();
  
  // useWatch 훅을 사용하여 password 필드의 값을 실시간으로 감시합니다.
  const password = useWatch({
    control,  // useWatch 훅은 control 객체를 필요로 합니다.
    name: "password"  // 감시할 필드의 이름을 지정합니다.
  });

  // 폼이 제출될 때 호출되는 함수입니다.
  // data 매개변수는 폼 입력값을 포함합니다.
  const onSubmit: SubmitHandler<FormInput> = (data) => console.log(data);

  return (
    // 폼 요소를 정의합니다.
    // handleSubmit 함수는 폼 제출을 처리하고, 유효성 검사를 실행합니다.
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        // password 필드를 폼에 등록하고 유효성 검사를 설정합니다.
        {...register("password", {
          required: "필수 값입니다.",  // 필수 입력 필드임을 정의합니다.
          minLength: {
            value: 7,
            message: "최소 7자 이상 입력해 주세요."  // 최소 길이를 7자로 설정하고 에러 메시지를 정의합니다.
          }
        })}
      />
      {/* password 필드에 에러가 있을 경우 에러 메시지를 출력합니다. */}
      {errors.password && <span>{errors.password.message}</span>}
      
      <input
        // passwordConfirm 필드를 폼에 등록하고 유효성 검사를 설정합니다.
        {...register("passwordConfirm", {
          required: "필수 값입니다.",  // 필수 입력 필드임을 정의합니다.
          validate: (value) =>
            value === password ? true : "비밀번호를 확인해 주세요."  // password 필드의 값과 일치하는지 확인합니다.
        })}
      />
      {/* passwordConfirm 필드에 에러가 있을 경우 에러 메시지를 출력합니다. */}
      {errors.passwordConfirm && <span>{errors.passwordConfirm.message}</span>}
      
      {/* 폼 제출 버튼입니다. */}
      <input type="submit" />
    </form>
  );
}
더보기
더보기
더보기

기존 watch 코드

// React Hook Form과 SubmitHandler를 임포트합니다.
import { useForm, SubmitHandler } from "react-hook-form";

// 폼 입력값의 타입을 정의하는 인터페이스를 선언합니다.
interface FormInput {
  password: string;
  passwordConfirm: string;
}

// 기본 컴포넌트 함수를 정의합니다.
export default function App() {
  // useForm 훅을 호출하여 폼 관련 메서드와 변수를 가져옵니다.
  // 여기서는 FormInput 인터페이스를 타입으로 사용합니다.
  const {
    register,  // 입력 필드를 폼에 등록하는 함수입니다.
    watch,  // 폼의 특정 필드 값을 실시간으로 감시하는 함수입니다.
    handleSubmit,  // 폼 제출을 처리하고, 유효성 검사를 실행하는 함수입니다.
    formState: { errors }  // 폼의 유효성 검사 오류를 포함하는 객체입니다.
  } = useForm<FormInput>();

  // 폼이 제출될 때 호출되는 함수입니다.
  // data 매개변수는 폼 입력값을 포함합니다.
  const onSubmit: SubmitHandler<FormInput> = (data) => console.log(data);

  // 컴포넌트의 JSX 반환값입니다.
  return (
    // 폼 요소를 정의합니다.
    // handleSubmit 함수는 폼 제출을 처리하고, 유효성 검사를 실행합니다.
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 비밀번호 입력 필드입니다. */}
      {/* register 함수는 입력 필드를 폼에 등록하고, 유효성 검사를 설정합니다. */}
      <input
        {...register("password", {
          required: "필수 값입니다.",  // 필수 입력값 유효성 검사와 에러 메시지입니다.
          minLength: {
            value: 7,
            message: "최소 7자 이상 입력해 주세요."  // 최소 길이 유효성 검사와 에러 메시지입니다.
          },
          deps: ["passwordConfirm"]  // passwordConfirm 필드의 종속성을 설정합니다.
        })}
      />
      {/* 비밀번호 필드의 유효성 검사 오류 메시지입니다. */}
      {errors.password && <span>{errors.password.message}</span>}
      
      {/* 비밀번호 확인 입력 필드입니다. */}
      <input
        {...register("passwordConfirm", {
          required: "필수 값입니다.",  // 필수 입력값 유효성 검사와 에러 메시지입니다.
          validate: (value) =>
            value === watch("password") ? true : "비밀번호를 확인해 주세요."  // 비밀번호 확인 유효성 검사와 에러 메시지입니다.
        })}
      />
      {/* 비밀번호 확인 필드의 유효성 검사 오류 메시지입니다. */}
      {errors.passwordConfirm && <span>{errors.passwordConfirm.message}</span>}
      
      {/* 제출 버튼입니다. */}
      <input type="submit" />
    </form>
  );
}

 

다른 점

 

기존

// useForm 훅에서 watch를 가져옵니다.
const {
  register,
  watch,
  handleSubmit,
  formState: { errors }
} = useForm<FormInput>();

// 폼 안에서 watch 함수를 사용하여 password 필드 값을 실시간으로 감시합니다.
validate: (value) =>
  value === watch("password") ? true : "비밀번호를 확인해 주세요."

 

useWatch

// useForm 훅에서 control을 가져옵니다.
const {
  register,
  handleSubmit,
  control,  // useWatch를 사용하려면 control을 가져와야 합니다.
  formState: { errors }
} = useForm<FormInput>();

// useWatch 훅을 사용하여 password 필드 값을 실시간으로 감시합니다.
const password = useWatch({
  control,  // useWatch는 control을 필요로 합니다.
  name: "password"  // 감시할 필드의 이름입니다.
});

// 폼 안에서 감시된 password 변수를 사용하여 유효성 검사를 수행합니다.
validate: (value) =>
  value === password ? true : "비밀번호를 확인해 주세요."

 

ErrorMessage 컴포넌트 ( 라이브러리 사용, 더 효율적 )

npm install @hookform/error-message
# or
pnpm add @hookform/error-message
# or
yarn add @hookform/error-message
import { useForm, SubmitHandler, useWatch } from "react-hook-form";
import { ErrorMessage } from "@hookform/error-message";

interface IFormInput {
  password: string;
  passwordConfirm: string;
}

export default function App() {
  // useForm 훅을 호출하여 폼 관련 메서드와 변수를 가져옵니다.
  // 여기서는 IFormInput 인터페이스를 타입으로 사용합니다.
  const {
    register,  // 입력 필드를 폼에 등록하기 위한 함수입니다.
    handleSubmit,  // 폼 제출을 처리하고, 유효성 검사를 실행하는 함수입니다.
    control,  // useWatch 훅을 사용하기 위해 필요한 객체입니다.
    formState: { errors }  // 폼의 유효성 검사 에러 정보를 포함합니다.
  } = useForm<IFormInput>();

  // useWatch 훅을 사용하여 password 필드의 값을 실시간으로 감시합니다.
  const password = useWatch({
    control,  // useWatch 훅은 control 객체를 필요로 합니다.
    name: "password"  // 감시할 필드의 이름을 지정합니다.
  });

  // 폼이 제출될 때 호출되는 함수입니다.
  // data 매개변수는 폼 입력값을 포함합니다.
  const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data);

  return (
    // 폼 요소를 정의합니다.
    // handleSubmit 함수는 폼 제출을 처리하고, 유효성 검사를 실행합니다.
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        // password 필드를 폼에 등록하고 유효성 검사를 설정합니다.
        {...register("password", {
          required: "필수 값입니다.",  // 필수 입력 필드임을 정의합니다.
          minLength: {
            value: 7,
            message: "최소 7자 이상 입력해 주세요."  // 최소 길이를 7자로 설정하고 에러 메시지를 정의합니다.
          }
        })}
      />
      {/* password 필드에 에러가 있을 경우 에러 메시지를 출력합니다. */}
      <ErrorMessage name="password" errors={errors} as="span" />
      
      <input
        // passwordConfirm 필드를 폼에 등록하고 유효성 검사를 설정합니다.
        {...register("passwordConfirm", {
          required: "필수 값입니다.",  // 필수 입력 필드임을 정의합니다.
          validate: (value) =>
            value === password ? true : "비밀번호를 확인해 주세요."  // password 필드의 값과 일치하는지 확인합니다.
        })}
      />
      {/* passwordConfirm 필드에 에러가 있을 경우 에러 메시지를 출력합니다. */}
      <ErrorMessage name="passwordConfirm" errors={errors} as="span" />
      
      {/* 폼 제출 버튼입니다. */}
      <input type="submit" />
    </form>
  );
}

 

라이브러리 안 쓴 코드랑 다른 점

 

안 씀

import { useForm, SubmitHandler, useWatch } from "react-hook-form";

// 에러 메시지를 직접 조건부 렌더링으로 표시
{errors.password && <span>{errors.password.message}</span>}
{errors.passwordConfirm && <span>{errors.passwordConfirm.message}</span>}

 

import { useForm, SubmitHandler, useWatch } from "react-hook-form";
import { ErrorMessage } from "@hookform/error-message";

// 에러 메시지를 ErrorMessage 컴포넌트를 사용하여 표시
<ErrorMessage name="password" errors={errors} as="span" />
<ErrorMessage name="passwordConfirm" errors={errors} as="span" />

//name 속성은 폼 필드의 이름 지정 (useForm 훅에서 등록된 필드 이름과 일치해야)
//errors={errors} 속성은 useForm 훅에서 제공하는 errors 객체 전달, 모든 폼 필드의 유효성 검사 에러 포함
//ErrorMessage 컴포넌트는 이 객체에서 name 속성으로 지정된 필드의 에러 메세지를 찾아서 표시
//as='span' 속성은 ErrorMessage가 어떤 html 요소로 렌더링될지를 지정함

 

if -> 알람 라이브러리를 사용한다면

import React from 'react';
import { useForm, SubmitHandler } from "react-hook-form";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

interface IFormInput {
  password: string;
  passwordConfirm: string;
}

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<IFormInput>();

  const onSubmit: SubmitHandler<IFormInput> = (data) => {
    console.log(data);
  };

  React.useEffect(() => {
    if (errors.password) {
      toast.error(errors.password.message); // 에러 메시지를 토스트로 표시
    }
    if (errors.passwordConfirm) {
      toast.error(errors.passwordConfirm.message); // 에러 메시지를 토스트로 표시
    }
  }, [errors]);

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        <input
          {...register("password", {
            required: "필수 값입니다.",
            minLength: {
              value: 7,
              message: "최소 7자 이상 입력해 주세요."
            }
          })}
        />
        
        <input
          {...register("passwordConfirm", {
            required: "필수 값입니다.",
            validate: (value) =>
              value === watch("password") ? true : "비밀번호를 확인해 주세요."
          })}
        />
        
        <input type="submit" />
      </form>
      <ToastContainer /> {/* 알람이 화면에 표시될 수 있도록 설정 */}
    </div>
  );
}

 

참고

더보기
더보기
더보기

https://velog.io/@yesoryeseul/react-hook-form-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90

 

react-hook-form 알고 쓰자

➡️ 먼저 react-hook-form이란 무엇인가? > Performant, flexible and extensible forms with easy-to-use validation. 유효성 검사를 쉽게 할 수 있는, 성능이 우수하고 유연하며 확장 가능한 form을 제

velog.io

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

 

React Hook Form 라이브러리 사용법

Engineering Blog by Dale Seo

www.daleseo.com

https://velog.io/@boyeon_jeong/React-Hook-Form

 

[React Hook Form] react hook form 기본 예시 따라하기

🕐❗❕❓❔🔅⚠⛔❌⭕✔➕➖✖💣💰📔📖🔗🏆🔥⚡😀😎🤓😭😵😲😨😱😮😪😩❤🧡👀☠React Hook Form은 React 유효성 검사와 폼 관리를 단순화하는 강력한💣 라이브러리입니다. 이 라

velog.io

https://beomy.github.io/tech/react/react-hook-form/

 

[React] react-hook-form으로 폼 관리하기

React Hook Form은 사용자 입력을 받고 검증하는 것을 도와 주는 라이브러리로, React에서 폼을 관리하는 가장 유명한 라이브러리 중 하나입니다. React Hook Form을 사용하면 사용자에게 입력을 받고 검

beomy.github.io

-> 진짜 유용, 설명도 더 많고 잘 되어있음

https://toby2009.tistory.com/50

 

React Hook Form의 useWatch와 watch 함수, 제대로 알고 쓰자!

살펴보기 React Hook Form은 React에서 폼을 쉽게 관리할 수 있도록 도와주는 라이브러리입니다. 이 라이브러리에는 폼의 상태를 추적하는 데 사용되는 두 가지 함수가 있습니다. 바로 useWatch와 watch

toby2009.tistory.com

'리액트' 카테고리의 다른 글

리액트 라우터 사용하기  (0) 2024.06.19
Use Effect가 필요한 이유  (0) 2024.06.18
리액트 쿼리 사용하기  (0) 2024.06.14
24. 06. 07 TIL redux-4  (0) 2024.06.07
24. 06. 05 TIL redux-3  (0) 2024.06.05