회원가입 탭에서 비밀번호를 입력 후 해당 비밀번호가 맞는지 한 번 더 확인하는 “비밀번호 확인” 인풋을 생성했다.
react-hook-form
환경에서useController
를 통해 Input 컴포넌트로 만든 상황이다.
비밀번호가 맞지 않을 시 '비밀번호가 일치하지 않습니다' 라는 에러가 발생하게끔 했는데, 문제가 있었다.
비밀번호 확인 값까지 입력한 상황에서, 다시 비밀번호 값을 바꿔도 비밀번호 확인 인풋에서 에러 메시지가 발생하지 않는 점이었다. 난 watch()
를 사용하여 비밀번호 값을 바꾸면 비밀번호 확인 값 또한 바뀌도록 validate
객체 안에서 useEffect
를 사용하려 했는데 이는 불가능했다.
그러던 중 외부에서 에러를 발생시킬 수 있는 setError
와 clearError
를 알게 되었는데, 오류를 직접 수동으로 설정할 수 있는 메서드였다.
setError 는 오류를 생성하는 메서드로, 첫번째 매개변수로 오류를 띄우길 원하는 인풋 name 을 넣고 그 외 오류 타입과 메시지는 다음과 같이 작성할 수 있다.
setError('passwordCheck', {
type: 'password-mismatch',
message: '비밀번호가 일치하지 않습니다'
})
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 || '비밀번호가 일치하지 않습니다'
}
}
}
}
/> ...