[React-hook-form] 비밀번호 일치 유효성체크

hyejinJo·2023년 10월 11일
0

React

목록 보기
8/9
post-thumbnail

회원가입 탭에서 비밀번호를 입력 후 해당 비밀번호가 맞는지 한 번 더 확인하는 “비밀번호 확인” 인풋을 생성했다. react-hook-form 환경에서 useController 를 통해 Input 컴포넌트로 만든 상황이다.
비밀번호가 맞지 않을 시 '비밀번호가 일치하지 않습니다' 라는 에러가 발생하게끔 했는데, 문제가 있었다.

비밀번호 확인 값까지 입력한 상황에서, 다시 비밀번호 값을 바꿔도 비밀번호 확인 인풋에서 에러 메시지가 발생하지 않는 점이었다. 난 watch() 를 사용하여 비밀번호 값을 바꾸면 비밀번호 확인 값 또한 바뀌도록 validate 객체 안에서 useEffect 를 사용하려 했는데 이는 불가능했다.

그러던 중 외부에서 에러를 발생시킬 수 있는 setErrorclearError 를 알게 되었는데, 오류를 직접 수동으로 설정할 수 있는 메서드였다.

setError

setError 는 오류를 생성하는 메서드로, 첫번째 매개변수로 오류를 띄우길 원하는 인풋 name 을 넣고 그 외 오류 타입과 메시지는 다음과 같이 작성할 수 있다.

setError('passwordCheck', {
        type: 'password-mismatch',
        message: '비밀번호가 일치하지 않습니다'
      })

clearError

clearError 는 말 그대로 에러를 수동으로 제거할 수 있다.

clearErrors('passwordCheck');

수정 후:


...
const { watch, control, setValue, getValues, handleSubmit, reset, setError, clearErrors, formState: { errors } } = useForm({
    mode: "onChange",
    defaultValues: {
      user: '',
      password: '',
      passwordCheck: '',
      term: false,
    },
  })

// [비밀번호] value 수정 시 이미 입력된 [비밀번호 확인] value 도 같이 유효성 체크
  useEffect(() => {
    if (watch('password') !== watch('passwordCheck') && watch('passwordCheck')) {
      setError('passwordCheck', {
        type: 'password-mismatch',
        message: '비밀번호가 일치하지 않습니다'
      })
    } else { // 비밀번호 일치시 오류 제거
      clearErrors('passwordCheck');
    }
  }, [watch('password'), watch('passwordCheck')])

return (
    <>
      <Input
        name="password"
        control={control}
        label="비밀번호"
        maxLength="15"
        type="password"
        placeholder='비밀번호(영문, 숫자, 특수문자 포함 8자 ~ 20자)'
        rules={
          {
            required: '비밀번호를 입력해주세요',
              pattern: {
                value: /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{8,20}$/,
                  message: '영문, 숫자, 특수문자 포함 8 ~ 20자로 입력해주세요'
              }
          }
        }
        />
      <Input
        name="passwordCheck"
        control={control}
        label="비밀번호 확인"
        type="password"
        maxLength="15"
        placeholder='비밀번호 확인'
        rules={
          {
            required: "비밀번호를 확인해주세요",
              validate: {
                matchPassword: (value) => {
                  const { password } = getValues();
                  return password === value || '비밀번호가 일치하지 않습니다'
                }
              }
          }
        }
        /> ...

결과:



참고: https://react-hook-form.com/docs/useform/seterror

profile
FE Developer 💡

0개의 댓글