[React] react-hook-form

rik963·2022년 6월 19일
0

React

목록 보기
9/9

react-hook-form은 React에서 form을 만들 때 사용하는 라이브러리이다. 대부분의 개발 프로젝트에서는 form을 사용하는데, 복잡한 형태의 form을 다루거나 validation, error type check 등의 기능이 필요할 때 간결한 코드로 구현이 가능하다.

react-hook-form의 장점

  • 기존의 폼에서 직접 구현해야 하는 번거로운 작업을 줄여준다. (validation, 데이터 전송 관리 등)
  • 타입스크립트와 아주 잘 맞는다.
  • 다른 라이브러리와 다르게 폼을 위한 컴포넌트나, 필드를 위한 컴포넌트가 없다.
  • 불필요한 렌더링을 최소화 하고, 마운팅이 빠르다.

설치

react-hook-form은 npm 또는 yarn으로 설치할 수 있다.

npm i react-hook-form

yarn add react-hook-form

useForm

useForm이라는 customized hook을 통해 react-hook-form 라이브러리에서 제공하는 기능을 사용할 수 있다.

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

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

useForm으로 받아온 property 중 개인적으로 자주 쓰는 것에 대해서 설명하겠다.

register

register은 form input 값의 name 지정, validation, error message 설정을 위해 사용되며, input의 props로 넣어준다.

<input
     {...register("password", {
       required: true,
       minLength: { value: 5, message: "Your password is too short." },
          })}
     placeholder="Password"
/>

위의 코드는 해당 input의 name을 'password'로 지정하고, password를 꼭 입력해야 하면서 입력값이 최소 5글자 이상이어야 한다는 validation을 설정한 것이다. 또한 password가 5글자 미만으로 입력될 시, 'Your password is too short.'라는 에러 메세지를 포함한 error를 발생시키도록 설정한 것이다.

required, minLength 외에도 다양한 validation 규칙이 있는데, 자세한 것은 아래 링크에서 확인할 수 있다.

List of validation rules supported:

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate

react-hook-form: register

handleSubmit

handleSubmit(onValid, onInvalid)은 위 register에 입력한 validation에서 통과가 되었을 때 onValid 함수를 발생시키고, 통과되지 못했을 때 onInvalid 함수를 발생시킨다. validation에 통과 시 input 값에 대한 정보를 받아올 수 있다.

function ToDoList() {
	const { register, handleSubmit } = useForm();
	const onValid = (data) => { console.log(data) };
	return (
      <form onSubmit={handleSubmit(onValid)}>
      	  <input {...register("firstName")} />
          <input {...register("lastName")} />
          <input {...register("userName")} />
          <input {...register("password")} />
          <input {...register("password1")} />
          <input {...register("email")} />
      </form>
	)
 };

만약 input의 validation에서 통과한다면 아래와 같은 형태로 input 값에 대한 정보를 얻을 수 있다.

errors

error에 대한 정보는 errors 함수를 통해 얻을 수 있다.

function ToDoList() {
	const { register, handleSubmit } = useForm();
	const onValid = (data) => { console.log(data) };
    console.log(errors);
	return (
      <form onSubmit={handleSubmit(onValid)}>
      	  <input {...register("firstName")} />
          <input {...register("lastName")} />
          <input {...register("userName", { required: "UserName is required"})} />
          <input {...register("password", {
            required: "Password is required",
            minLength: { value: 5, message: "Your password is too short." },
          })} />
          <input {...register("password1")} />
          <input {...register("email")} />
      </form>
	)
 };

해당 form에서 userName을 입력하지 않고 password를 다섯 글자 미만으로 작성한다면, validation에 통과하지 못하고 error를 발생시킬 것이다. errors로 받아온 정보의 형태는 아래와 같다.

setError, reset

register에 작성한 validation rule 외에 추가로 validation을 해주고 싶으면 setError 함수를 이용하면 된다. 또한 form의 validation이 모두 통과되었을 때 입력값을 초기화하고 싶으면 reset 함수를 이용하면 된다.

const onValid = (data: IForm) => {
	// password와 password1이 같아야 한다는 validation 추가
    if (data.password !== data.password1) {
      setError(
        "password1",
        { message: "Password are not the same" },
        { shouldFocus: true }
      );
    };
    
    // network validation 추가
    if (true) {
      setError("extraError", { message: "Server offline." });
    };
    
    // 모든 validation에서 통과할 경우 입력값 초기화
    reset();
  };

코드 작성 예시

아래 코드는 react-hook-form 라이브러리 활용 예시이다.

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

interface IForm {
  firstName: string;
  lastName: string;
  userName: string;
  password: string;
  password1: string;
  email: string;
  extraError?: string;
}

function ToDoList() {
  const {
    register,
    handleSubmit,
    formState: { errors },
    setError,
    reset,
  } = useForm<IForm>();
  const onValid = (data: IForm) => {
    if (data.password !== data.password1) {
      setError(
        "password1",
        { message: "Password are not the same" },
        { shouldFocus: true }
      );
    }
    reset();
  };
  return (
  	<div>
      <form
        onSubmit={handleSubmit(onValid)}
      >
        <input
          {...register("userName", {
            required: "UserName is required",
            validate: {
              noWoong: (value) =>
                value.includes("woong") ? "no woong allowed" : true,
              noWong: (value) =>
                value.includes("wong") ? "no wong allowed" : true,
            }, 
          })}
          placeholder="User Name"
        />
        <span>{errors?.userName?.message}</span>
        <input
          {...register("password", {
            required: "Password is required",
            minLength: { value: 5, message: "Your password is too short." },
          })}
          placeholder="Password"
        />
        <span>{errors?.password?.message}</span>
        <input
          {...register("password1", {
            required: "Password1 is required",
            minLength: { value: 5, message: "Your password1 is too short." },
          })}
          placeholder="Password1"
        />
        <span>{errors?.password1?.message}</span>
        <input
          {...register("email", {
            required: "Email is required",
            pattern: {
              value: /^[A-Za-z0-9._%+-]+@naver\.com$/,
              message: "Only naver.com emails allowed.",
            },
          })}
          placeholder="Email"
        />
        <span>{errors?.email?.message}</span>
      </form>
    </div>
  )
 };

react-hook-form

0개의 댓글