- [React Hook Form] React Hook Form 공부 - 18 (유효성 검증(Validation)의 심화 방식) [7/26 study]2024년 07월 26일 07시 22분 23초에 업로드 된 글입니다.작성자: 동혁이
React Hook Form 공부 - 18
유효성 검증(Validation)의 심화 방식
우리가 React-Hook-Form을 쓰는 이유는 클라이언트 상에서 유효성 검증을 쉽게 하기 위해서 인데요.
그래서 React-Hook-Form은 유효성 검증에서 다음과 같은 3가지의 심화된 방식도 제공합니다.
첫 번째, 비동기식 유효성 검증입니다.
간혹 커스텀 Validation할 때 외부 사이트에서 정보를 가져와서 비교할 때가 있는데요.
비동기식(async,await) 방식도 지원합니다.
이메일 부분에 지난 시간에 만든 커스텀 Validation이 2개가 있었는데요.
한 개를 추가해 보겠습니다.
이 Validation은 비동기식으로 통신해서 얻은 결과를 비교하게 됩니다.
코드의 간결성을 위해 username과 email만 남기겠습니다.
type FormValues = { username: string; email: string; }; export default function MyForm() { const { register, control, handleSubmit, watch, getValues, setValue, reset, formState: { errors, touchedFields, dirtyFields, isDirty, isValid, isSubmitting, isSubmitted, isSubmitSuccessful, submitCount, }, } = useForm<FormValues>({ defaultValues: { username: "IU", email: "", }, }); ... ... ... <label htmlFor="email">E-mail</label> <input type="email" id="email" {...register("email", { pattern: { value: /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/, message: "Email is invalid.", }, validate: { noAdmin: (fieldValue) => { return ( fieldValue !== "admin@fly.dev" || "You can not use admin@fly.dev!" ); }, noBlackList: (fieldValue) => { return ( !fieldValue.endsWith("daum.net") || "This domain is not supported." ); }, emailCheck: async (fieldValue) => { const response = await fetch( `https://jsonplaceholder.typicode.com/users?email=${fieldValue}` ); const data = await response.json(); return data.length == 0 || "Email already exists"; }, }, })} /> <p>{errors.email?.message}</p> ... ... ... }
위와 같이 emailCheck이란 커스텀 Validation을 추가했습니다.
REST API는 기존처럼 jsonplaceholder를 사용했고요.
해당 이메일이 있으면 즉, 배열의 갯수가 0이 아니라면 "Email already exists" 문구를 에러 메시지로 내보냅니다.
테스트를 위해 아래 button submit의 disabled 항목에서 isValid 부분만 지우겠습니다.
<button disabled={!isDirty || isSubmitting}>Submit</button>
실행 결과는 위와 같습니다.
기존에 이메일 있다고 에러가 나오네요.
두 번째, Validation 모드를 제공해 줍니다.
React-Hook-Form은 Validation을 언제 시행할 지도 옵션으로 제공해 주는데요.
다음 그림처럼 총 5가지가 있습니다.
all, onBlur, onChange, onSubmit, onTouched
디폴트는 'onSubmit'입니다.
submit 버튼을 눌렀을 때 Validation 행위가 일어나는 겁니다.
onBlur 는 커서를 input에 위치시켰다가 다시 input 폼을 벗어난 곳에 클릭하게 되면 이때 Validation 행위가 일어나게 됩니다.
만약, email 부분에 required 항목을 추가했다고 합시다.
그러면, email에 커서를 놓았다고 다시 화면 밖을 클릭하면 폼을 벗어난게 되어서 onBlur에 의해 Validation 행위가 일어나며 Email 부분에 에러 메시지가 뜨게 됩니다.
세 번째, onTouched 는 onBlur 방식을 일부 빌린겁니다.
onBlur 방식이 커서가 input 태그를 벗어났을 때 Validation 행위가 일어나는 거라면,
onTouched 방식은 첫 번째 blur Event에 실행되며, 그 이후로는 아무 변화(onChange)에도 반응합니다.
onChange 방식은 한 글자 한 글자 칠 때마다 Validation 행위가 일어나는 겁니다.
마지막으로 all 방식은 onBlur + onChange 방식을 조합한 방식입니다.
Validation mode는 브라우저의 과부하를 유발할 수 있으니 주의하여 선택 하시기 바랍니다.
모드를 지정하는 방법은
const { register, control, handleSubmit, watch, getValues, setValue, reset, formState: { errors, touchedFields, dirtyFields, isDirty, isValid, isSubmitting, isSubmitted, isSubmitSuccessful, submitCount, }, } = useForm<FormValues>({ defaultValues: { username: "IU", email: "", }, mode: 'onSubmit' // 여기 });
위 코드에서 지정하면 됩니다.
세 번째, 수동으로 Validation 행위를 하라고 지시할 수 있습니다.
trigger 함수를 불러오면 되는데요.
const { register, control, handleSubmit, watch, getValues, setValue, reset, trigger // 여기 formState: { errors, touchedFields, dirtyFields, isDirty, isValid, isSubmitting, isSubmitted, isSubmitSuccessful, submitCount, }, } = useForm<FormValues>({ defaultValues: { username: "IU", email: "", }, mode: 'onSubmit' });
그리고, 맨 밑에 버튼을 추가해 봅시다.
<button type="button" onClick={() => trigger()}> Validate </button>
위와 같이 작성하면 이 버튼을 누를 때마다 수동으로 Validation 행위를 일으킬 수 있습니다.
아니면 필요한 부분만 일으킬 수 도 있는데요.
<button type="button" onClick={() => trigger("email")}> Validate </button>
여러 개를 넣고 싶으면 문자열의 배열 방식으로 쓰시면 됩니다.
다음글이 없습니다.이전글이 없습니다.댓글