react-hook-form & yup 유효성 검사하기

nevermind·2022년 9월 2일
2
post-custom-banner

react-hook-form으로 유효성 검사하기

  • yarn add react-hook-form
  • 설명
    • register : input 요소를 React hook form과 연결시켜 검증 규칙을 적용할 수 있게 하는 메소드
    • formState : form state에 관한 정보를 담고 있는 객체
    • handleSubmit:
      form을 submit했을 때 실행할 함수. Validation을 통과했을때 실행할 콜백함수(SubmitHandler)가 반드시 필요하다. 실패했을때의 콜백함수(SubmitErrorHandler)는 옵셔널.
import React from 'react'
//추가하기
import {useForm} from 'react-hook-form'
import styled from 'styled-components'


const Login = () => {
  const { register,handleSubmit,formState: {isSubmitting,errors}} = useForm();
  const onClickLogin = (data) => {
        console.log(data)
    }
    

    return (
<form onSubmit={handleSubmit(onClickLogin)}>
   <InputBox>
      <h2>로그인</h2>
    <InputBoxInner>
          <input id='userId' name='id' placeholder='ID'  {...register('userId', {
            required: true,})} />
    <Errorsmessage>
            {errors.userId?.type === 'required' && '아이디를 입력하세요'} 
    </Errorsmessage>

    <input id='password' name='password' type='password' placeholder='PASSWORD'
    {...register('password',{
      required: true,
      pattern: {
        value:
        /(?=.*\d{1,50})(?=.*[~`!@#$%\^&*()-+=]{1,50})(?=.*[a-zA-Z]{2,50}).{8,16}$/,
        message:
        '비밀번호를 8~16자로 영문 대소문자, 숫자, 특수기호를 조합해서 사용하세요. ',
      }
    })} />
    <Errorsmessage>
      {errors.password?.type === 'required' && '비밀번호를 입력해주세요'}
    {errors.password?.type === 'pattern' && errors.password.message}
      </Errorsmessage>
     {/* 로그인 버튼창 */}
     <button type='submit' disabled={isSubmitting}>로그인</button>
     <KakaoButton>카카오 소셜 로그인</KakaoButton>

     </InputBoxInner>
     <SignMove>아직 회원이 아니신가요?</SignMove>
  </InputBox>
</form>
    )
}
//styled 컴포넌트는 생략!


yup

  • react-hook-form와 함께 사용할 수 있는 validation package들이 있는데 그 중 yup을 많이 사용한다고 한다
    - 출처: https://codiving.kr/63
  • yarn add react-hook-form @hookform/resolvers yup
import React from 'react'
import { useForm } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup'
import styled from 'styled-components'

const schema = yup.object().shape({
  nickname: yup.string()
    .min(2, "닉네임은 최소 2글자 이상입니다!")
    .max(10, "닉네임은 최대 10글자입니다!")
    .matches(
      /^[가-힣a-zA-Z][^!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\s]*$/,
      "닉네임에 특수문자가 포함되면 안되고 숫자로 시작하면 안됩니다!")
    .required('닉네임을 입력해주세요'),
  // checkNickname: yup.boolean().required('중복체크해주세요'),
  id: yup.string()
    .min(3, '3자 이상 입력해주세요!')
    .matches(
      /^[가-힣a-zA-Z][^!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?\s]*$/,
      "닉네임에 특수문자가 포함되면 안되고 숫자로 시작하면 안됩니다!")
    .required('아이디를 입력해주세요'),
  pw: yup.string()
    .max(16, "비밀번호는 최대 16자리입니다!")
    .matches(
      /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}[^\s]*$/,
      "알파벳, 숫자, 공백을 제외한 특수문자를 모두 포함한 8자리 이상 입력해주세요"
  )
    // .matches(regexPasswd, '비밀번호를 8~16자로 영문 대소문자, 숫자, 특수기호를 조합해서 사용하세요.')
    .required('비밀번호를 입력해주세요'),
  checkPw: yup
    .string()
    .oneOf([yup.ref('pw'), null], '비밀번호가 일치하지 않습니다')
    .required('비밀번호를 한번 더 입력해주세요'),
  certifi_email: yup.string()
    .email('이메일형식이 적합하지 않습니다.')
    .required('이메일 인증해주세요'),
})

const SignUp = () => {
  const { register, handleSubmit, formState: {  errors },reset } = useForm({
    resolver: yupResolver(schema),
    mode: 'onChange' 
  });

  const onClickLogin = (data) => {
    console.log(data)
    reset();
  }

  return (
<form onSubmit={handleSubmit(onClickLogin)}>
  <InputBox>
  	<h2>회원가입</h2>
    <InputBoxInner>
      <InputFlex>
        <InputWithButton id='nickname' name='nickname' placeholder='nickname' 
{...register('nickname')} />
        <CheckButton id='checkNickname' name='checkNickname'>중복확인</CheckButton>
      </InputFlex>
     <Errorsmessage>{errors.nickname?.message}</Errorsmessage>

     <InputFlex>
       <InputWithButton id='userId' name='id' placeholder='ID'  {...register('id')} />
     <CheckButton>중복확인</CheckButton>
     </InputFlex>
     <Errorsmessage>{errors.id?.message} </Errorsmessage>

     <OnlyInput id='password' name='pw' type='password' placeholder='PASSWORD'
     {...register('pw', {required: true})} />
     <Errorsmessage> {errors.pw?.message}
     </Errorsmessage>

     <OnlyInput id='checkPsasword' name='checkPw' type='password' placeholder='checkPassword'
     {...register('checkPw', {
       required: true
     })} />
     
     <Errorsmessage>
       {errors.checkPw?.message}
     </Errorsmessage>
     
     <OnlyInput id='certifi_email' name='certifi_email' type='email' placeholder='이메일인증'
     {...register('certifi_email', {
       required: true
     })} />
     <Errorsmessage>
       {errors.certifi_email?.message}
     </Errorsmessage>
     
     {/* 로그인 버튼창 */}
     <SignupButton type='submit' >회원가입</SignupButton>
     </InputBoxInner>
 	</InputBox>
 </form>

  )
}

  • 회원가입 버튼을 누르면 입력하지 않은 값들의 에러메세지가 뜬다

submit되기 전에 미리 유효성메세지 보여주기!

formik없이 할 수 있다

  const { 
    register, handleSubmit, formState: { 
      errors },reset } = useForm({
    resolver: yupResolver(schema),
    mode: 'onChange' 
  });
  • onBlur 이벤트 발생할 때 validation 발생시키기
    사용자가 submit 버튼을 누르기 전에 form에 입력한 값이 유효한 값이 아니라는 것을 미리 표시해주는 것이 좀 더 나은 UX를 제공한다고 생각하는데, 이를 가능하게 해주는 것이 mode이다.
    mode는 useForm()에 넘겨줄 수 있는 다양한 optional arguments 중 하나로 사용자가 form을 submit 하기 전에 validation이 실행될 수 있게 해준다.

  • mode에 사용 가능한 값
    mode: onChange | onBlur | onSubmit | onTouched | all = 'onSubmit'

  • onBlur 이벤트가 발생할때마다 validation이 실행된다.
    const { register } = useForm({mode: 'onBlur'})

출처: https://velog.io/@sweetpumpkin/React-hook-form%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-Form-Validation

profile
winwin
post-custom-banner

0개의 댓글