TIL - 2022.08.12

이정우·2022년 8월 12일
0

TIL

목록 보기
3/3

TIL - 2022.08.12

React에서 form은 아주 다양하게 쓰인다.

하지만 그에 비해 form을 만드는 과정은 아주 복잡하다.

  1. form, input 태그 생성
  2. useState를 통해 state를 생성 후 input의 value에 state 연결
  3. onChange 이벤트 리스너 함수 생성 후 input의 이벤트에 연결
  4. submit 핸들러 생성 후 연결
  5. validation 코드 작성

등등 여러 과정이 필요하다.

import { useState } from "react";

export default function Form() {
  const [id, setId] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [idError, setIdError] = useState("");
  const [emailError, setEmailError] = useState("");
  const [passwordError, setPasswordError] = useState("");

  const onIdChange = (e) => {
    const {
      target: { value }
    } = e;

    setId(value);
  };

  const onEmailChange = (e) => {
    const {
      target: { value }
    } = e;

    setEmail(value);
  };

  const onPasswordChange = (e) => {
    const {
      target: { value }
    } = e;

    setPassword(value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    // validation
    if (!id) {
      setIdError("Id is required");
      return;
    }

    if (!email) {
      setEmailError("Email is required");
      return;
    }

    if (!password) {
      setPasswordError("Password is required");
      return;
    }

    if (!email.includes("@gmail.com")) {
      setEmailError("You should use gmail");
      return;
    }

    // Sign Up 처리
    alert("sign up success!");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        required
        placeholder="Id"
        value={id}
        onChange={onIdChange}
      />
      {idError}
      <br />
      <input
        type="email"
        required
        placeholder="Input Gmail"
        value={email}
        onChange={onEmailChange}
      />
      {emailError}
      <br />
      <input
        type="password"
        required
        placeholder="Password"
        value={password}
        onChange={onPasswordChange}
        minLength="10"
      />
      {passwordError}
      <br />
      <input type="submit" value="Sign Up" />
    </form>
  );
}

핵심 로직이 없는데도 input 태그의 값 제어를 위해 너무 많은 시간이 필요하다.

또한, 사용자의 좋은 경험을 위해서는 고려해야 할 것이 많은데 저렇게 일일히 작성하다 보면 하나 둘씩 까먹고 만들지 못한 기능이 생길 수도 있다.
ex) Validation 이후 입력시 바로 에러 메세지 수정, 에러난 곳으로 focus 이동 등

react-hook-form

리액트의 라이브러리 중 하나인 react-hook-form을 사용하면 좀 더 쉽게 form을 만들 수 있다.

npm i react-hook-form

register

register(name: string, RegisterOptions?) => ({ onChange, onBlur, name, ref })

첫번째 인자로 input의 이름, 두번째 인자로 여러 옵션들을 전달하면 손쉽게 input과 state를 연결할 수 있다.

옵션에는 required, minLength, max, pattern, validate 등 여러 값을 줄 수 있는데, validate를 제외한 값들은 HTML의 input 태그와 동일하게 작동한다.

validate에는 함수를 전달하여 원하는 방식으로 validation을 수행할 수 있다.

watch

watch(names?: string | string[] | (data, options) => void) => unknown

register를 통해 state에 등록한 여러 input의 값들을 객체로 받아올 수 있다.

모든 값을 받아올 수도 있으며, 특정 값을 받아오는 것도 가능하다.

formState

isSubmitted, isSubmitSuccessful, errors 등 여러 상태를 가지는 객체이다.

register에서 등록한 에러도 formState의 errors에 등록되는데, 등록한 이름과 에러 타입, 메세지가 매핑되어 저장된다.

handleSubmit

handleSubmit((data: Object, e?: Event) => void, (errors: Object, e?: Event) => void) => Function

onSubmit 이벤트의 핸들러로, 첫번째 인자로 성공했을 경우 실행할 함수와 두번째 인자로 실패했을 경우 실행할 함수를 넘겨주면 된다.

react-hook-form을 적용한 코드

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

export default function NewForm() {
  const {
    register,
    formState: { errors },
    handleSubmit
  } = useForm();

  const handleOnValid = () => {
    console.log("success");
  };

  const handleOnInValid = () => {
    console.log(errors);
  };

  return (
    <form onSubmit={handleSubmit(handleOnValid, handleOnInValid)}>
      <input
        type="text"
        {...register("id", {
          required: "Id is required"
        })}
        placeholder="Id"
      />
      {errors.id?.message}
      <br />
      <input
        type="email"
        {...register("email", {
          required: "Email is required",
          validate: {
            onlyGmail: (email) =>
              email.includes("@gmail.com") || "You should use Gmail"
          }
        })}
        placeholder="Email"
      />
      {errors.email?.message}
      <br />
      <input
        type="password"
        {...register("password", {
          required: "Password is required",
          minLength: {
            message: "password has to be more than 10 characters",
            value: 10
          }
        })}
        placeholder="Password"
      />
      {errors.password?.message}
      <br />
      <input type="submit" value="Sign Up" />
    </form>
  );
}

사용하지 않았을 때에 비해 가독성도 좋아지고 길이도 훨씬 짧아진 것을 볼 수 있다.

이외에도 여러 기능이 있으니 잘 사용하면 좋을것 같다!

참고

react-hook-form 공식 홈페이지

0개의 댓글