본문으로 바로가기

[React] react-hook-form 소개 및 사용 전

category 공유/React, Next 2022. 4. 17. 13:30

[React] react-hook-form 소개 및 사용 전

예전에 react-hook-form에 대해 작성한 적이 있었다. 이 때 react-hook-form을 제대로 이해하지 못 한 부분이 있었고, 다시 읽어보니 material-ui와 함께 사용하는 부분만 적혀있는 듯한 느낌이 들었다. 따라서 이번에 다시 공부해보며 정리해보려고 한다.

react-hook-form 소개

우선 여기서 설명하는 react-hook-form은 Version 7을 의미합니다. react는 사용하던, vue, angular 등 웹 환경에서 form data를 다루어야하는 경우는 매우 많이 있습니다. 대표적으로 회원가입을 할 경우 input form을 사용하지 않기는 힘들 것 같습니다. 회원가입을 구현할 경우 validation 처리, 값 관리 등 해야할 일이 많이 있는데 react-hook-form은 react에서 form 다룰 때 많은 도움을 줍니다. 어떠한 도움을 주는 지 react-hook-form을 사용하기 전, react-hook-form을 사용한 후 2개 다 비교해보도록 하겠습니다.

◆ 구현할 내용

name, age, id, password, email 구현

모든 input field는 required

데이터 type -> age: number, 그 외 : string

name : 5글자 이상, 10글자 이하

age : 10살 이상, 100살 이하

password : 영어만 가능

email은 @gmail.com 만 가능

간단하게 회원가입하는 form을 만들어볼 예정입니다. 조건은 위와 같이 있습니다. 실제로 구현 가능한 내용을 가지고 구현해볼 예정입니다. 따라서 약간의 validation도 추가하였고 react만 사용한 경우와, react-hook-form에서는 어떻게 간단하게 구현할 수 있는 지 알아보도록 하겠습니다. 우선 react만 사용하여 구현하겠습니다.

react-hook-form 사용하기 전

react만을 이용하여 위 조건을 구현해보았습니다. (모든 내용 구현 x) 아래 코드를 확인해봅시다.

import { useState } from "react";

interface IUserData {
  name: string;
  age: number;
  id: string;
  password: string;
  email: string;
}

const initUserData = {
  name: "",
  age: 0,
  id: "",
  password: "",
  email: ""
};

const initErrors = {
  name: "",
  age: "",
  id: "",
  password: "",
  email: ""
};

const UserRegisterOnlyReact = () => {
  const [userData, setUserData] = useState<IUserData>(initUserData);
  const [errors, setErrors] = useState(initErrors);

  const onHandleUserData = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value, name } = e.target;

    setUserData(prev => ({
      ...prev,
      [name]: name === "age" ? Number(value) : value
    }));
  };

  return (
    <form
      onSubmit={e => {
        e.preventDefault();

        const { name, age, id, password, email } = userData;
        const domain = email.split("@")[1];

        if (domain !== "gmail.com") {
          setErrors(prev => ({
            ...prev,
            email: "gmail 형식이 아닙니다."
          }));
          return;
        }

        // ... 필수 값이 입력되지 않았습니다. (코드 작성 해야함)
        // ... name은 5글자 이상, 10글자 이하이어야 합니다. (코드 작성 해야함)
        // ... age는 10 이상, 100 이하이어야 합니다. (코드 작성 해야함)
        // ... password가 모두 영어인지 작성해야함
        // ... email이 gmail인지 확인해야함
        // ... 기타 등등 테스트 작성

        // ... 모든 테스트 통과
        setErrors(initErrors);
        console.log("# name", name);
        console.log("# age", age);
        console.log("# id", id);
        console.log("# password", password);
        console.log("# email", email);
      }}
    >
      <input
        value={userData["name"]}
        onChange={onHandleUserData}
        placeholder="name"
        name="name"
        required
        maxLength={10}
        minLength={5}
      />
      <input
        value={userData["age"]}
        onChange={onHandleUserData}
        placeholder="age"
        name="age"
        required
        type="number"
        min={10}
        max={100}
      />
      <input
        value={userData["id"]}
        onChange={onHandleUserData}
        placeholder="id"
        name="id"
        required
      />
      <input
        value={userData["password"]}
        onChange={onHandleUserData}
        placeholder="password"
        name="password"
        required
        type="password"
      />
      <input
        value={userData["email"]}
        onChange={onHandleUserData}
        placeholder="email"
        name="email"
        required
        type="email"
      />
      {!!errors.email && <span>{errors.email}</span>}
      <input type="submit" />
    </form>
  );
};

export default UserRegisterOnlyReact;

 

위 코드는 너무 간단하게 따로 코드에 대한 설명은 하지 않겠습니다. 그러나 코드를 확인해보면 약간 불편한(문제점) 부분이 있습니다. 우선 data, errors state가 확장성이 없습니다. 다시 말하면 input field개 1개 추가되거나 삭제될 때마다 state도 추가, error handling도 추가 ... 등 해주어야 할 작업이 많이 있습니다. 그리고 onSubmit 이후 모든 input에 대한 error handling을 각각 해주어야 합니다. 이러한 경우 실수를 할 확률이 많이 있습니다. 또한 마지막 문제의 경우는 매우 희박하지만 사용자가 직접 개발자 도구를 통해 input element를 수정할 수 있습니다. 위 코드의 경우 이러한 경우를 생각하여 error handling을 추가로 하였습니다. 해당 조작하는 것을 아래 이미지로 확인해봅시다.

위와 같이 사용자가 임의로 조작할 수 있습니다. 그렇게 되면 required가 아닌 채로 동작하게 됩니다. 결국 backend에서 데이터를 저장할 때 걸러지겠지만 이러한 경우를 frontend에서 미리 걸러주면 더욱 좋을 것 같습니다. 위에서 확인해본 모든 문제를 react-hook-form을 이용하면 해결할 수 있습니다. 다음 게시글에서는 react-hook-form을 이용하여 위 조건에 맞는 코드를 구현해보겠습니다.

 

참고자료

 

마지막

해당 내용은 틀릴 수도 있습니다. 틀린 내용이 있으면 조언 부탁드립니다.

반응형