⚛︎React Hook Form

zooyaho·2022년 6월 11일
0
post-thumbnail

React Hook Form

: React Hook Form 라이브러리
: 유효성 검증에 유용하다(vaildation)

📎 설치

npm i react-hook-form

📎 import

import {useForm} from 'react-hook-form'

📎 메서드

● register, watch

register메서드

  • input요소의 value, 이벤트메서드 등을 가지는 객체를 반환한다.
  • 인수로 요소의 key를 지정한다.
  • spread문법을 사용하여 요소에 register메서드를 props로 전달한다.

👾

console.log(register("Email"));

<InputWrap>
  <label htmlFor="firstName">first name</label>
  <input {...register("firstName")} id="firstName" type="text" placeholder="firstName"></input>
</InputWrap>

watch메서드

  • form의 모든 입력값들의 변화를 확인할 수 있다.
  • ex) watch("toDo"): "toDo"에 해당하는 요소의 value만 확인 가능함!, 빈 요소일 경우 모든 요소의 변화하는 값들을 확인 가능.
  • onChange이벤트 함수와 비슷함.

👾01

const { register, watch } = useForm();
  console.log(watch());
  return(
    <div>
      <form>
        <input {...register("Email")} placeholder="Email" />
        <input {...register("Password")} placeholder="Password" />
        <input {...register("FirstName")} placeholder="FirstName" />
        <input {...register("LastName")} placeholder="LastName" />
        <button>Add</button>
      </form>
    </div>
  );

● handleSubmit

handleSubmit메서드

  • onSubmit이벤트 핸들러를 대체.
  • validation을 담당(유효성 검사).
  • form의 onSubmit에 등록
  • handleSubmit(onValid, onInvalid)
    • onValid: 데이터가 유효할 때 호출되는 함수 -> 필수
    • onInvalid: 데이터가 유효하지 않을 때 호출되는 함수 -> 옵션

👾02

const {register, handleSubmit} = useForm();
const onValid = (data:any)=>{
 // 이 함수는 react-hook-form이 모든 validation을 다 마쳤을때만 호출 됨.
    console.log(data);
};
  return(
    <div>
      <form onSubmit={handleSubmit(onValid)}>
        <input {...register("Email", {required:true})} placeholder="Email" />
        <input {...register("Password", {required:true})} placeholder="Password" />
        <input {...register("Password1", {required:true})} placeholder="Password" />
        <input {...register("FirstName", {required:true})} placeholder="FirstName" />
        <input {...register("LastName", {required:true})} placeholder="LastName" />
        <button>Add</button>
      </form>
    </div>
  );

👾 자바스크립트에서 validation하기

<input {...register("Email", {required:true, minLength:10 }) } placeholder="Email" />

👉🏻 <input required placeholder="Email" /> 처럼 HTML에 의존하여 사용할 경우 사용자가 소스코드를 수정하여 required를 삭제할 수 있음.
👉🏻 required를 지원하지 않는 브라우저나, 모바일에서 보거나 소스코드를 수정한다면 해당 기능을 사용하지 못하게 됨.
👉🏻 그러므로 자바스크립트에서 validation을 하는 것이 좋음!!
👉🏻 비어있는 요소로 커서가 이동하게 됨.

● formState

formState함수 : 다양한 기능이 있음.

👾 formState.errors: 에러 발생 시 어떤 에러인지 알려줌, 에러가 발생한 요소들을 객체형태로 반환함.

 const { formState: { errors } } = useForm();
console.log(formState.errors);

👾 에러 메세지 설정

console.log(formState.errors);
...
<input {...register("Email", {required:"Email is required", minLength: 10})} placeholder="Email" />
<input {...register("Password", {required:true, minLength: {value:5, message:"Your password is too short"}})} placeholder="Password" />
...

👉🏻 minLength등 에러 메세지와 값을 같이 설정할 수 있음.

👾 정규표현식으로 validation하기

<input {...register("Email", 
        { required: "Email is required", 
          pattern: {
            value: /^[A-Za-z0-9._%+-]+@naver.com$/,
            message: "Only naver.com emails allowed",
          }, 
          minLength: 10})
       } placeholder="Email" />

👉🏻 pattern: regexp 또는 pattern:{value: regexp, message: ""}

👾 화면에 에러 메세지 출력하기

const {formState:{errors} } = useForm();
...
<input {...register("Email", 
        { required: "Email is required", 
          pattern: {
            value: /^[A-Za-z0-9._%+-]+@naver.com$/,
            message: "Only naver.com emails allowed",
          }, 
          minLength: 10})
       } placeholder="Email" />
<span style={{color:"red"}}>{errors?.Email?.message}</span>
...

👉🏻 제출을 해야 에러메세지가 출력됨.
👉🏻 에러타입에 따른 메세지 출력을 조건 설정하지 않아도, 에러타입에 해당하는 메세지를 출력해줌!!

👾 validate: FN - 인자로 항목에 현재 쓰이고 있는 값을 받음, true/false를 반환.

...
<input {...register(
  "firstName", 
  { 
    required: "write here", 
    validate: (value) => value.includes("mark")? "no mark allowed": true 
  })}
 placeholder="First Name" />
...

👉🏻 false를 반환할 경우 error타입으로 'validate'로 설정됨.
👉🏻 문자열을 반환할 경우 error message가 반환됨.

<input
  {...register("firstName", {
    required: "write here", 
    validate: {
      noMark: (value) => value.includes("mark") ? "no mark allowed" : true,
      noLee: (value) => value.includes("lee") ? "no lee allowed" : true
    }
  })} 
  placeholder="First Name"
/>
<span>{errors?.firstName?.message}</span>

👉🏻 noMark, noMark와 같이 여러개의 vaildation을 만들 수 있음

👉🏻 또한 validate: asynk FN로 비동기 함수로 만들어서 서버에다 확인받고 응답을 받을 수 있음.
👉🏻 회원가입 폼에서 가입할 아이디가 서버에 등록된 아이디인지 검사하고 에러를 발생시킬 경우 사용하게 된다.

● setError

setError : 특정한 에러를 발생시킴.

  • 에러 발생 요소에 포커싱을 하려면 shouldFocus:true를 설정 해야한다.

👾 password와 password1이 같지 않을 경우 error 메세지 출력

const {
    register,
    handleSubmit,
    formState: { errors },
    setError // 특정한 에러를 발생시킴.
  } = useForm<IForm>({
    defaultValues: {
      email: "@naver.com", // 기본값 설정
    },
  });
  const onValid = (data: IForm) => {
    // 이 함수는 react-hook-form이 모든 validation을 다 마쳤을때만 호출 됨.
    if (data.password !== data.password1) {
      setError("password1", { message: "Password are not the same" }, { shouldFocus:true });
    }
  };


👉🏻 {shouldFocus:true} : 에러 발생 시 해당 요소에 포커스 설정

👾 전체 폼에 대한 에러 - 누군가 서버를 해킹해서, 서버가 다운되어 접속이 끊길경우 에러 메세지 출력

interface IForm {
  email: string;
  firstName: string;
  lastName: string;
  password: string;
  passwordConfirm: string;
  extraError?: string; // 속성 추가
}
...
const onValid = (data: IForm) => {
  setError("extraError", { message: "Server Offline." });
};
...
// 에러 메세지 출력할 곳에 작성
<span>{errors?.extraError?.message}</span>
...

● setValue

setValue : 값이 검사를 통과하면 input을 비움.

👾

...
const { register, handleSubmit,setValue, formState: { errors } } = useForm<IForm>();
const handleValid = (data: IForm) => {
  console.log("add to do.", data.todo);
  setValue("todo","");
}
...

👉🏻 submit후 validation을 모두 통과하면 todo요소의 값이 비어짐.

📎 타입스크립트 사용 시

☁️ interface설정, defaultValues설정 가능

interface IForm {
  email: string;
  firstName: string;
  lastName: string;
  username: string;
  password: string;
  password1: string;
  extraError?: string;
}
...
const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<IForm>({
    defaultValues: {
      email: "@naver.com",
    },
  });
...

✏️ 연습한 프로젝트: https://github.com/zooyaho/react-formhook-practice
react-hook-form 공식 사이트

profile
즐겁게 개발하자 쥬야호👻

0개의 댓글