React-Hook-Form

e-pong:)·2022년 11월 28일
0

React에서 hook 사용 규칙

함수형 컴포넌트내 최상위 영역에서 hook을 호출해야 한다.

  • 해당 규칙으로 랜더링마다 hook 호출 순서가 보장된다.
  • 조건문, 반복문 안에서 hook을 호출하지 않는다.
  • 중첩된 함수 안에서 hook을 호출하지 않는다.

custom hook 내부에서 hook을 호출해야한다.

  • custom hook은 javaScript 일반함수이다.
  • custom hook의 함수명은 use를 prefix로 갖도록 한다.

React-Hook-Form

react-hook-form 사용 이유

관리해야하는 상태관리가 늘어나는 만큼 handler, validation function 선언도 늘어난다.
관련하여 에러 메시지도 추가 될 것이다.
마지막으로 submit function의 로직이 복잡하고 비대해질 것으로 예상된다.
react-hook-form은 위에서 언급한 고민에 대한 해결책을 제공한다.

  1. register 함수를 통해 입력값 등록 단순화
  2. handleSumbit 함수를 통해 preventDefault 보일러플레이트 제거 및 함수인자로 form 값 전달

react-hook-form 설치 및 예시

React Hook Form을 설치하는 것은 단 하나의 명령어만 있으면 된다.

npm install react-hook-form

다음 코드 발췌는 기본 사용 예를 보여준다.

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

export default function App() {
  const { register, handleSubmit, watch, formState: { errors } } = useForm();
  const onSubmit = data => console.log(data);

  console.log(watch("example")); // watch input value by passing the name of it

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input defaultValue="test" {...register("example")} />
    
      <input {...register("exampleRequired", { required: true })} />
      {errors.exampleRequired && <span>This field is required</span>}
      
      <input type="submit" />
    </form>
  );
}

등록 필드

React Hook Form의 핵심 개념 중 하나는 구성 요소를 후크에 연결하는 것이다. 이렇게 하면 양식 유효성 검사 및 제출 모두에 해당 값을 사용할 수 있다.

각 필드는 등록 프로세스를 위한 키로 있어야 한다. name

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

export default function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = data => console.log(data);
   
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <select {...register("gender")}>
        <option value="female">female</option>
        <option value="male">male</option>
        <option value="other">other</option>
      </select>
      <input type="submit" />
    </form>
  );
}

유효성 검사

React Hook Form은 양식 유효성 검사를 위한 기존 HTML 표준과 정렬하여 양식 유효성 검사를 쉽게 만든다.

지원되는 유효성 검사 규칙 목록

  • 필수의 (required)
  • 최소 길이 (minLength)
  • 최대 길이 (maxLength)
  • 최소 (min)
  • 최대 (max)
  • 패턴 (pattern)
  • 확인 (validate)
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = data => console.log(data);
   
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true, maxLength: 20 })} />
      <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
      <input type="number" {...register("age", { min: 18, max: 99 })} />
      <input type="submit" />
    </form>
  );
}

오류 처리

React Hook Form은 양식 errors의 오류를 표시하는 개체를 제공한다. errors 유형은 주어진 유효성 검사 제약 조건을 반환한다.
다음 예는 필수 유효성 검사 규칙을 보여준다.

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

export default function App() {
  const { register, formState: { errors }, handleSubmit } = useForm();
  const onSubmit = (data) => console.log(data);
  
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input 
        {...register("firstName", { required: true })} 
        aria-invalid={errors.firstName ? "true" : "false"} 
      />
      {errors.firstName?.type === 'required' && <p role="alert">First name is required</p>}

      <input 
        {...register("mail", { required: "Email Address is required" })} 
        aria-invalid={errors.mail ? "true" : "false"} 
      />
      {errors.mail && <p role="alert">{errors.mail?.message}</p>}
      
      <input type="submit" />
    </form>
  );
}

React-Hook-Form 구현해보기

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

import "./styles.css";

function App() {
  const { register, handleSubmit ,watch, formState : {errors}} = useForm();
  console.log(watch("email"));
  const password = useRef();
  password.current = watch('password');

  const onSubmit = data => {
    console.log(data);
    // axios.post('/',data) ...
  }
  

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>Email</label>
      <input
        //name="email"
        type="email"
        {...register("email", { required: true, pattern: /^\S+@+\S+$/i })}
      />
      {errors.email && <p>This email field is required</p>}

      <label>Name</label>
      <input
        {...register('name', { required: true, maxLength : 10})}
      />
      {errors.name && errors.name.type === 'required'&& <p>This field is required</p>}
      {errors.name && errors.name.type === 'maxLength' && <p>Your input exceed maxium length</p>}

      <label>Password</label>
      <input
        type="password"
        {...register("password", { required: true , minLength:6})}
      />
      {errors.password && errors.password.type === 'required' && <p>This field is required</p>}
      {errors.password && errors.password.type === 'minLength' && <p>Your input exceed minium length</p>}

      <label>Password Confirm</label>
      <input
        type="password"
        {...register("password_confirm", { required: true, validate : (value) => value === password.current})}
      />
      {errors.password_confirm && errors.password_confirm.type === 'required' && <p>This field is required</p>}
      {errors.password_confirm && errors.password_confirm.type === 'validate' && <p>The passwords do not match</p>}

      <input type="submit" />
    </form>
  );
}

export default App;

resister()의 값으로 value를 넣어주기 때문에 name 속성이 꼭 필요한게 아니라면, name 속성을 입력하지 않고 {...register('email')}로 제어가 가능하다.

name 속성의 값과 상관없이 watch() 안에 들어오는 value는 register()의 value이다.

errors는 useForm()을 구조분해해서 바로 꺼내오는 것이 아니라,
const {register, formState(errors)} = useForm() 처럼 선언해야 한다.

useRef를 이용해서 PasswordPassword Comfirm 이 같은지 비교할려면 아래와 같다.

  1. ref 생성
  2. watch를 이용하여 password 필드 값 가져오기
  3. 가져온 password 값을 ref.current에 넣어주기
profile
말에 힘이 있는 사람이 되기 위해 하루하루, 성장합니다.

0개의 댓글