React Hook Form

Blackeichi·2022년 9월 30일
1
post-custom-banner

react-hook-form은 사용하기 쉬운 유효성 검사를 통해 성능이 뛰어나고 유연하며 확장 가능한 form이다.

// Less code (c)
// Better validation(c)
// Better Erros (set, clear, display)(c)
// Have control over inputs(c)
// Dont deal with events (c)
// Easier Inputs (c)

아래의 두 코드를 보며 비교해보자!🤔

일반 Form사용

  export default function Forms() {
    const [username, setUsername] = useState("");
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [formErrors, setFormErrors] = useState("");
    const [emailError, setEmailError] = useState("");
    const onUsernameChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
      const {
        currentTarget: { value },
      } = event;
      setUsername(value);
    };
    const onEmailChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
      const {
        currentTarget: { value },
      } = event;
      setEmailError("");
      setEmail(value);
    };
    const onPasswordChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
      const {
        currentTarget: { value },
      } = event;
      setPassword(value);
    };
    const onSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
      event.preventDefault();
      //dev를 위해 새로고침을 막음
      if (username === "" || email === "" || password === "") {
        setFormErrors("All fields are required");
      }
      //프론트엔드에서 minLength나 required 등을 설정해도, 개발자도구에서 지울 수 있기때문에
      //이렇게 막아놔야함. 하지만 이것은 너무 비효율적이라 react-form-hook을 사용함
      if (!email.includes("@")) {
        setEmailError("email is required");
      }
    };
    return (
      <form onSubmit={onSubmit}>
        <input
          value={username}
          onChange={onUsernameChange}
          type="text"
          placeholder="Username"
          required
          minLength={5}
        />
        <input
          value={email}
          onChange={onEmailChange}
          type="email"
          placeholder="Email"
          required
        />
        {emailError}
        <input
          value={password}
          onChange={onPasswordChange}
          type="password"
          placeholder="Password"
          required
        />
        <input type="submit" value="Create Account" />
      </form>
    );
  }

React-Hook-Form 사용

  import { FieldErrors, useForm } from "react-hook-form";
  interface LoginForm {
    username: string;
    password: string;
    email: string;
    setErrors ?: string
    //errors는 required가 아님.
  }
  export default function Forms() {
    const { register, handleSubmit,watch,formState: { errors },setValue, setError,reset, resetField,
    //formState는 errors를 사용할 수 있음. 이걸로 errors.~~.message를 화면에 출력가능
    //reset은 onValid 와 같은 함수에 reset()을 넣으면 모든 form이 초기화되는 것이다.
    //resetField는 특정 필드만 초기화
    } = useForm<LoginForm>({
      mode: "onChange",
      //onChange로 하면 submit버튼을 누르지 않아도 유저가 값을 입력하는 순간 유효하지 않으면 실시간으로 출력됌
      //onBlur, onSubmit 등등 여러 종류가 있음
    });
    //handleSubmit은 onValid(form이 유효할 때 실행되는 함수)와 onInValid(form이 유효하지 않을 때 실행되는 함수) 두 가지 함수를 받을 수 있다.
    console.log(watch());
    //input에 입력되는 값이 그대로 console.log됌
    const onValid = (data: LoginForm) => {
      console.log("im valid bby");
      setError("setErrors", {message : "Backend Error"})
      //setError는 특정한 필드에 관한 에러가 아니더라도 에러를 설정할 수 있게 해주는 것
    };
    const onInvalid = (errors: FieldErrors) => {
      console.log(errors);
    };
    setValue("username", "hello");
    //username input에 value를 hello로 넣어준다. 직접 value를 설정
    return (
      {errors.setErrors?.message}
      <form onSubmit={handleSubmit(onValid, onInvalid)}>
        <input
          {...register("username",{
              required: "Username is required",
              //required 다음에 적은 내용이 onInValid에서 errors.message에 들어간다.
              minLength: {
              message: "The username should be longer than 5 chars.",
              value: 5,
            },)}//errors.type에 어떤 validation이 유효하지 않은지 볼 수 있다.
          //username이 key, value가 되는 것
          //form에 handleSubmit을 넣고 이렇게 required 와 같은 validation을 사용하면 해당 input이 유효하지 않을 때, 실행을 막아준다.
          type="text"
          placeholder="Username"
        />
        <input
          {...register("email", {
            required: "Email is required",
            validate: {
              notGmail: (value) =>
                !value.includes("@gmail.com") || "Gmail is not allowed",
            },
            //notGmail이라는 validation을 추가하는 것. 이메일주소에 gmail이 들어가 있으면, errors.email.message에 들어감.
          })}
          type="email"
          placeholder="Email"
          classname={`${Boolean(errors.email?.message) ? "border-red-500" : ""}`}
          //에러 메세지가 있으면 border 색을 변하게 하는등 여러 가지 custom 가능
        />
        {errors.email?.message}
        .................
      ```

다만 input의 component를 만들고, 불러와서 사용한다면 다음과 같이 사용해야 한다.

   <Input
   register={register("email", {
     required: true,
   })}
   name="email"
   label="Email address"
   type="email"
   required
 />

#REFERENCE

react-hook-form 공식 홈페이지
노마드코더

profile
프론트엔드 주니어 개발자 한정우입니다. 😁
post-custom-banner

0개의 댓글