[React-Javascript]React-hook-form을 이용한 유효성 체크

이은지·2023년 12월 5일
0

React

목록 보기
6/11

🔆리액트 훅 폼을 사용하는 이유

  • 보통 회원가입 페이지를 만들면 id, passwor, email 등등 많은 값들이 필요하게 되고, useState 훅을 이용해 만들게 되면, onChange 핸들러를 그 수에 맞게 만들고,validation 함수도 그에 맞게 만들어야 함.그럼 자연스럽게 해당 값들을 관리할 state들이 늘어나게 됨.

  • 그에 따른 문제점

  1. 코드의 길이 증가
  2. 모든 값이 state로 연결되어 있어 하나의 값이 변할 때마다 여러 개의 자식 컴포넌트 들에서 무수히 많은 리랜더링이 발생

🔆What is React Hook Form

React Hook Form 라이브러리는 React에서 사용자로부터 데이터를 수집하는 form을 쉽게 관리하기 위한 라이브러리

Reack Hook Form은 React hooks를 사용하여 폼을 처리하기 때문에 사용하기 간단한 편이며 폼을 처리하는데 필요한 기능을 쉽게 구현할 수 있음

React Hook Form은 폼처리를 위해 불필요한 렌더링을 최소화하고 성능을 향상시키기 위해 최적화 되어있어 성능 문제를 방지할 수 있음

🔆React-Hook-Form 패키지 설치

npm install react-hook-form

🔆React-hook-form 사용하기

1. useForm 훅 구조

  • 해당 훅에 파라미터로 객체를 넘길 수 있으며, 여러가지 configuration 옵션이 들어갈 수 있음
  • 그 중 modedefaultValues를 가장 많이 활용
  • mode
    • validation 전략 설정 시 활용, onSubmit, onChange, onBlur, all 등의 옵션이 있음
    • mode를 onchange로 할 경우, 다수의 리렌더링 발생할 수 있음
  • defaultValues
    • form에 기본 값을 제공하는 옵션
    • 기본값을 제공하지 않을 경우, input의 초기값은 undefined로 관리됨
export type UseFormProps<TFieldValues extends FieldValues = FieldValues, TContext = any> = Partial<{
    mode: Mode;
    reValidateMode: Exclude<Mode, 'onTouched' | 'all'>;
    defaultValues: DefaultValues<TFieldValues>;
    resolver: Resolver<TFieldValues, TContext>;
    context: TContext;
    shouldFocusError: boolean;
    shouldUnregister: boolean;
    shouldUseNativeValidation: boolean;
    criteriaMode: CriteriaMode;
    delayError: number;
}>;

const model = useForm({
  mode: "onChange",
  defaultValues: {},

});

2. useForm훅을 통해 리턴 받는 객체

  • useForm을 통해 컨트롤 할 폼 객체를 리턴받아 destructuring하여 각 함수를 꺼내 사용할 수 있음
export type UseFormReturn<TFieldValues extends FieldValues = FieldValues, TContext = any> = {
    watch: UseFormWatch<TFieldValues>;
    getValues: UseFormGetValues<TFieldValues>;
    getFieldState: UseFormGetFieldState<TFieldValues>;
    setError: UseFormSetError<TFieldValues>;
    clearErrors: UseFormClearErrors<TFieldValues>;
    setValue: UseFormSetValue<TFieldValues>;
    trigger: UseFormTrigger<TFieldValues>;
    formState: FormState<TFieldValues>;
    resetField: UseFormResetField<TFieldValues>;
    reset: UseFormReset<TFieldValues>;
    handleSubmit: UseFormHandleSubmit<TFieldValues>;
    unregister: UseFormUnregister<TFieldValues>;
    control: Control<TFieldValues, TContext>;
    register: UseFormRegister<TFieldValues>;
    setFocus: UseFormSetFocus<TFieldValues>;

};

register

  • 해당 함수를 통해 input태그를 다룸

  • 첫번째 매개변수: input의 name

  • 두번째 매개변수: options 객체(유효성 검사를 위한 프로퍼티)

    • required, min, max, minLength, maxLength, pattern 등..
    • value, message로 구성된 객체를 줌으로써 해당 에러에 대한 구체적인 메시지를 제공할 수 있음
     <input
       type="text"
       {...register("email", {
         pattern: {
           value:
             /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i,
           message: "이메일 형식에 맞지 않습니다.",
         },
       })}
    
     />;
     

formState

  • register 함수에 validation을 넣어준 뒤, formState 객체의 errors에서 에러에 대한 정보 찾을 수 있음
  • 에러가 존재하지 않는다면 해당 객체는 빈 객체이고, 검증을 통해 에러가 발생한다면 해당 객체에 name의 객체가 생기고, 그 객체 속에 error의 타입과 메시지가 담김
  • errors 뿐만 아니라 submitCount, dirtyFields, isValid 등 다양한 정보를 확인할 수 있음

watch

  • 폼에 입력된 값을 구독하여 실시간으로 체크할 수 있게 해주는 함수
const {id, name, pwd, ...watch} = watch(); //전체 필드를 리턴

const id = watch("id");
  • 매개변수를 주지 않는다면 전체 값을 관찰할 수 있으며, 매개변수를 준다면 해당 값만 관찰할 수 있음
{watch("occupation") === "professor" ? (
  <Row>
    <Label>phone: </Label>
    <ControlInputText<IForm> control={control} name="phone" />
  </Row>
) : null
}
  • 만약 관찰하려는 필드에 defaultValue를 주지 않는다면, 초기 값이 undefined로 관리가 됨

getValues

  • watch 함수와 같이 사용자에게 입력된 값을 반환하지만 리렌더링을 발생시키지 않고 해당 값을 추적하지 않는 함수
const handleEvent = (event) => {
  const value = getValues("name");
  setState(value);
}

reset

  • 폼 데이터 수정 시 활용하는 함수

handleSubmit, setError, setFocus

  • submit 이벤트 발생 시 서버에 데이터를 넘기기 전 데이터를 검증하기 위한 함수
  • 최종 데이터 검증을 하다가 어떤 에러가 체크되었다면 setError 함수를 활용하거나, setFocus를 활용해 해당 필드에 포커스를 줄 수 있음

🔆React-hook-form을 이용하여 유효성 체크하기

  1. 회원가입 폼에 React Hook Form 연결하기
  • react-hook-form 패키지로 부터 useForm() 훅(hook) 함수를 불러온 후, 컴포넌트 함수 안에서 이 함수를 호출함
  • 그러면 결과 객체로부터 register() 함수와 handleSubmit() 함수를 얻을 수 있음
    • register() : input 요소를 등록하는 함수로 각각의 input 요소에 대한 Reference를 생성하고 유효성 검사를 위한 다양한 옵션을 전달할 수 있음
    • handleSubmit(): 폼(Form)을 제출할 때 호출되는 함수로 폼 데이터를 수집하고, 폼 내에 인풋 요소에 대한 유효성 검사를 실행함
import {useForm} from 'react-hook-form'

const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();
  1. 입력값 검증
  • 입력값 검증은 입력란을 등록할 때, register()함수의 두 번째 인자로 옵션을 넘기면 됨
  • HTML에서 입력란 검증을 위해 기본적으로 제공되는 required, patter, minLength와 같은 검증 타입을 사용할 수 있으며, 각 검증 타입이 실패했을 때 보여줄 오류 메시지를 설정 가능
  • 입력란에 유효하지 않은 값을 입력했을 경우 검증이 실패하여 로그인 폼이 제출되지 않고, formState 속성의 errors 객체에 오류 내용이 저장됨
    • 해당 값을 읽어 오류 메세지 렌더링 가능

<s.SignForm onSubmit={handleSubmit(onSubmit)}>
	<s.SignLabel>아이디</s.SignLabel>
	<s.SignInput type="text" name="uid" placeholder='4~15자 이내로 작성해주세요' 
	
	{errors.uid && <span className="error">{errors.uid.message}</span>}
	
	<s.SignLabel>비밀번호</s.SignLabel>
	<s.SignInput type="password" name="password" placeholder='최소 6자 이상(알파벳, 숫자 필수)'
	{...register('password', 
			{required: '비밀번호를 입력하세요',
		    pattern: {
	      value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/,
	      message: '알파벳과 숫자를 포함한 최소 6자 이상이어야 합니다',
	    }
	})}/>
	{errors.password && <span className="error">{errors.password.message}</span>}
	
<s.SignLabel>이메일</s.SignLabel>
	<s.SignInput type="email" name="email" placeholder='festivalholic@gmail.com'
	{...register('email', {
	  required: '이메일을 입력하세요',
	  pattern: {
	    value: /^[A-Za-z0-9]([-_.]?[A-Za-z0-9])*@[A-Za-z0-9]([-_.]?[A-Za-z0-9])*\.[A-Za-z]{2,3}$/,
	    message: '이메일 형식을 확인해주세요',
	  }
	})}/>
	 {errors.email && <span className="error">{errors.email.message}</span>}
	
	<s.SignButton>회원가입</s.SignButton>
</s.SignForm>

(참고) https://www.daleseo.com/react-hook-form/
https://tech.osci.kr/introduce-react-hook-form/

profile
소통하는 개발자가 꿈입니다!

0개의 댓글