useForm을 활용한 Validation 검사

박상하·2023년 2월 22일
0

React

목록 보기
5/7

State Management 파트를 진행하면서 useForm으로 입력값에 대한 타당성 검사를 하는 법을 학습하였다.
useForm을 사용하니 코드의 수가 많이 줄어들었지만 여전히 헷갈리는 부분이 존재하고
이를 이해하기위해 이곳에 정리를 해보려한다!

먼저 useForm을 사용하지 않고 3개의 입력값을 받아오는 코드를 짜보았다.

const Test=()=>{
 const [Id,setId] = useState("")
 const [Password,setPassword] = useState("")
 const [CheckPass,setCheckPass] = useState("")
  
 const IdChange=(event: React.FormEvent<HTMLInputElement>)=>{
   setId(event.currentTarget.value)
 }
 const PasswordChange=(event: React.FormEvent<HTMLInputElement>)=>{
   setPassword(event.currentTarget.value)
 }
 const CheckChange=(event: React.FormEvent<HTMLInputElement>)=>{
   setCheckPass(event.currentTarget.value)
 }
 const onSubmit=(event: React.FormEvent<HTMLFormElement>)=>{
   
   if(Id.length<10){
   console.log("에러가 발생했네요!")
   }
   if(Password.length<10){
   console.log("에러가 발생했네요!")
   }
   if(CheckPass.length<10){
   console.log("에러가 발생했네요!")
   }
   
 }
 
<return>
  <div>
  <form onSubmit={}>
  <input onChange={IdChange} value={Id} placeholder="ID"/>
  <input onChange={PasswordChange} value={Password} placeholder="PassWord"/>
  <input onChange={CheckChange} value={CheckPass} placeholder="CheckPassWord"/>
  
  </form>
  </div>
}

위 코드가 같이 각 Input마다 State를 지정해주고 각 Input에 변화가 있을 때 마다 State를 새롭게
업데이트 해주어야해서 코드의 양이 많아졌었다. 이를 해소시켜주는 useForm 라이브러리이다!

useForm은 다양한 메서드를 제공한다.

설치방법

npm install react-hook-form

메서드는 register, watch, hangleSubmit, formState 등 다양한데 이를 하나씩 살펴보도록 하겠다.

register는 원하는 input에 생명력을 넣어줍니다.

register를 console.log() 해보면

const {register} = useForm()
console.log(register("d"))

name, onChange, onBlur, ref 의 속성을 가진 Object가 반환된다.

name은 해당 Input을 찾는 Key가 된다. 그리고 register를 input의 속성으로 등록을 하면
안에 있는 onChange의 역할로 "State"를 따로 설정해주지 않아도 된다!!

name이 state의 이름이 되고 그 값은 watch() 라는 라이브러리 메서드를 통해 알 수 있다.

코드로 정리해보면 이렇다.

const Test=()=>{
 
  const {register,watch}=useForm()
  
  return <div>
    <form>
    <input {...register("ID")} placeholder="ID"/>
    <input {...register("PASS")} placeholder="PASS"/>
    <input {...register("CHECK")} placeholder="CHECK"/>
    //이렇게 되면 state명은 각 안에 들어있는 string이 되고 내부의 값은 실시간으로 추적이된다! 
    //여기서 console.log(watch())를 해보면 
    
    </form>
  //이렇게 state에 대한 설정이 필요가 없다!
  //완전사기
    </div>
  
}

console.log(watch()) 를 찍었을 때 모습

값이 바뀔 때마다 register의 onChange가 그 값을 추적해준다.

또, register 메서드의 좋은점은 속성을 JS형태로 계속 집어넣을 수 있다는 점이다.
spread operator를 이용하여 register의 내부에 있는 Object를 Input의 속성으로 넣은 아이디어를
이용하여 추가로 속성을 넣어줄 수 있다. 이때 유용한 속성은 maxLength,minLength,pattern등이 있다.

const Test=()=>{
 
  const {register,watch}=useForm()
  
  return <div>
    <form>
    <input {...register("ID",{require:true, maxLength:10})} placeholder="ID"/>
    <input {...register("PASS",{require:true, maxLength:5})} placeholder="PASS"/>
    <input {...register("CHECK",{require:true, minLength:3})} placeholder="CHECK"/>
    
    </form>
    </div>
  
}

속성을 넣어 줄 때 value와 message를 구분하여 넣을 수 있다. message는 만약 통과를 하지 못했을 때 사용하게 된다

const Test=()=>{
 
  const {register,watch}=useForm()
  
  return <div>
    <form>
    <input {...register("ID",{require:true, maxLength:{
    value:10,
      message:"10글자가 최대입니다!"
    }})} placeholder="ID"/>
    <input {...register("PASS",{require:true, maxLength:5})} placeholder="PASS"/>
    <input {...register("CHECK",{require:true, minLength:3})} placeholder="CHECK"/>
    
    </form>
    </div>
  
}

그렇다면 이러한 Message를 사용하게 되는 경우 즉 , 타당성을 검사하는 함수는 무엇일까??

handleSubmit

handleSubmit은 보통 form 태그에 onSubmit에 들어간다.

위 함수는 두 가지의 인자를 받을 수 있는데 타당성 검사가 성공했을 때의 함수, 그리고 타당성 검사가 실패했을 때의 함수

즉 이런식으로 사용된다.

const pass =(data)=>{
console.log(data)}
const fail =()=>{
 console.log("실패!") 
}
<form onSubmit={handleSubmit(pass,fail)}></form>

위 함수를 하면 성공했을 때 다음 동작을 이어나갈 수 있다. 또는 실패했을 때 다음동작을 이어나갈 수 있다.

그렇다면 타당성 검사가 끝났을 때 에러메세지를 어떻게 접근할 수 있을까??
어떤 Input이 에러가 났는지 알 수 있는 함수가 있다.

formState

먼저 formState 역시 React-Form-hook 라이브러리에서 가져온 함수이다.

formState를 console.log()로 찍어보면

다음과 같다. 다양한 정보를 가져올 수 있는데 그 중 errors를 통해 어떤 Input이 error 인지 알 수 있다. Submit 했을 때 handleSubmit 함수에서 타당성 검사를 진행하고
formState는 타당성 검사 결과를 보여준다.

다음과 같이 보여준다!
Email
:
{type: 'required', message: '필수입력사항입니당!', ref: input}
First_name
:
{type: 'required', message: '필수입력사항입니당!', ref: input}
Last_name
:
{type: 'required', message: '필수입력사항입니당!', ref: input}
Password
:
{type: 'required', message: '필수입력사항입니당!', ref: input}
User_name
:
{type: 'required', message: '필수입력사항입니당!', ref: input}

그렇다면 errors.message로 유저에게 해당 메세지를 보여줄 수 있는 것이다!!!


즉 정리하면 이렇다!!

🖍 register 로 Input의 value에 변화를 감지하고 해당 value를 특정할 수 있도록 한다.
🖍 watch() 함수로 이 변화 값을 실시간 가져올 수 있다.
🖍 타당성 검사를 하고싶다면 먼저 handleSubmit 함수를 form onSubmit의 변수로 집어넣는다
🖍 handleSubmit은 타당성 검사를 진행하고 만약 타당하다면 실행될 함수, 실패했다면 실행될 함수가 작동한다.
🖍 forState는 오류가 난 부분에 접근할 수 있다. 정확히 오류가 난 Input에 접근이 가능하다

setError

나만의 custom Error를 발생시키고 싶다면 setError를 사용하면된다,
이 역시 useForm 라이브러리에서 가져온 메서드로 특정한 에러를 발생시킬 때 사용된다.

이런식으로 사용이 가능하다.

const Pass =(data)=>{
if(data.PASS!==data.CHECK){
 return setError("PASS",{message:"에러가 발생했습니다."}) 
  
}
}

<form onSubmit={handleSubmit(pass)}></form>

또한 각 Input마다 고유의 타당성 검사를 진행하고 싶다면 다음과 같이 하면 된다.

<input
          {...register("ID", {
            required: { value: true, message: "필수입력사항입니다." },
            validate: (value) => value.includes("nico"),
          })}
          placeholder="ID"
        />
//위 value는 input의 value가 된다.

확장도 가능하다.

<input
          {...register("ID", {
            required: { value: true, message: "필수입력사항입니다." },
            validate:{
          checkNico:(value) => value.includes("nico"),
            checkPark:(value)=>value.includes("park")
            },
          })}
          placeholder="ID"
        />

0개의 댓글