[React] React Hook Form

Davina·2022년 12월 23일
0

All Empty Study 🫥

목록 보기
1/16

React Hook Form

React 내에서 Form을 쉽게 제어하고 손쉽게 유효성 검사를 처리하도록 도와주는 라이브러리

적용 예시 ⬇️

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

export default function App() {
  const { register, handleSubmit, errors } = useForm();

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

  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>
				<label htmlFor="email">이메일</label>
        <input type="text" name="email" placeholder="test@email.com" {...register("email"} />

				<label htmlFor="password">비밀번호</label>
        <input type="password" name="password" ref={register} /> //or {...register("password")}
        <button type="submit">Login</button>
      </form>
    </div>
  );

패키지 설치

npm install react-hook-form

React Hook Form 사용

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

React Hook Form은 form 작업에 사용할 수 있는 useForm hook을 제공합니다. hook은 초기값 설정, 입력 필드 지우기 기능 등을 제공하지만, 제일 중요한 세 가지는 상기의 것

[register]

ref로 사용되는 함수로 입력 필드를 React Hook Form에 등록하고 변경 사항에 대해 값을 추적합니다.

<input type="text" name="email" ref={register} />
⭐ 입력 필드에는 name 속성이 있어야 하며 해당 값은 고유해야 한다!

[handleSubmit]

form을 서버로 제출할 때 사용하는 함수입니다.

<form onSubmit={handleSubmit(onSubmit)}>

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

[errors]

유효성 검사를 포함하는 객체입니다.

<input type="text" name="email" ref={register({ required: true})} />
<input
  type="password"
  name="password"
  ref={register({ required: true, minLength: 6 })}
/>

validation 기본 구현

validation를 추가하기 위해서는 각 입력 필드 ref로 전달되는 레지스터 함수에 유효성 검사를 매개변수를 전달합니다.

<input type="text" name="email" ref={register({ required: true})} />
<input
  type="password"
  name="password"
  ref={register({ required: true, minLength: 6 })}
/>

유효성 검사 속성들

  • required: 입력 필드에 대한 필수 여부 검사
  • minlength maxlength: 문자열 입력 값의 최소, 최대 길이 설정
  • min max: 숫자 입력 값의 최소값, 최대값 설정
  • type: 입력 필드에 대한 유형 (이메일, 숫자, 텍스트 등)
  • pattern: 정규식을 이용한 입력 필드에 대한 패턴 정의

이렇게 정의된 속성들에 따라 form이 제출될 때 errors로 유효성 검사 성공여부를 확인할 수 있습니다.

<input
  type="text"
  name="email"
	error={errors.email?.message === undefined ? "" : "error"}
  ref={register("email", {
    required: {value: true, message:'Email is required.'},
    pattern: {
      value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
      message: 'Email is not valid.'
    }
  })}
/>

{errors.email && errors.email.type === "required" && (
  <p className="errorMsg">{errors.email?.message}</p>
)}

[validation 검사]

기본적으로 유효성 검사는 handleSubmit 함수가 실행될 대 진행됩니다. 유효성 검사가 실패하면 React Hook Form은 다음과 같이 처리합니다.

  • 해당 입력 필드에 자동으로 focus 처리
  • errors가 하나라도 존재할 경우 submit 함수 미처리 (form 제출을 안함)

사용자 정의 validation

validate 함수를 추가하여 입력 필드에 대한 사용자 지정 유효성 검사를 제공할 수도 있습니다.

const validatePassword = (value) => {
  if (value.length < 6) {
    return '6자리보다 적게 입력해주세요.';
  }
  return true;
};

<input
  type="password"
  name="password"
  ref={register({
    required: '비밀번호는 필수값입니다.',
    validate: validatePassword
  })}
/>

React Hook Form 라이브러리 사용법

예시

  • 비밀번호
const onValid = async (data) => {
        if (data.password !== data.passwordConfirm) {
            setError(
                "passwordConfirm",
                { message: "비밀번호가 다릅니다." },
                { shouldFocus: true }
            );
        }

        try {
            await axios
                .post("http://localhost:3001/signup", data)
                .then((data) => {
                    Toast.fire({
                        title: "회원가입 성공!",
                        icon: "success",
                        customClass: {
                            icon: "icon-class",
                            container: "my-swal",
                        },
                    });
                    setSignupOpen(false);
                    dispatch(modalOpen());
                });
        } catch (error) {
            console.error(error);
        }
    };

<ModalInputBox onSubmit={handleSubmit(onValid)}>

<div>
	<label htmlFor="password">비밀번호</label>
	<input
		id="password"
		type="password"
		placeholder="8자 이상의 숫자, 영대소문자, 특수문자 포함"
		{...register("password", {
        required: "비밀번호를 입력해주세요.",
        pattern: {
        value: /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,25}$/,
        message:
	        "숫자+영문자+특수문자 조합으로 8자리 이상 입력해주세요!",
        },
     })}
  />
  <ErrorBox>
	   {errors?.email?.message === undefined ? null : (
         <BiErrorCircle />)
		 }{errors?.password?.message}
  </ErrorBox>
</div>

</ModalInputBox>
  • 이메일
<div>
	<label htmlFor="email">이메일</label>
	<input
		id="email"
		type="text"
		placeholder="address@email.com"
			{...register("email", {
				required: "이메일을 입력해주세요.",
				pattern: {
					value: /^[^@ ]+@[^@ ]+\.[^@ .]{2,}$/,
					message:"올바른 이메일 형식이 아닙니다.",
				},
			})}
	/>
	<ErrorBox>
		{errors?.email?.message === undefined ? null : (
			<BiErrorCircle />)
		}{errors?.email?.message}
	</ErrorBox>
</div>
profile
[많을 (다) 빛날 (빈)] 빛이나는 사람이 되고 싶습니다

0개의 댓글