본문 바로가기

Front/React

[React] Form Validation (Formik VS React Hook Form)

Validation 이란?

서버에 데이터를 제출하기 전에 양식이 올바른지 확인하는 과정

사용자가 데이터를 목적지로 보내기 전에, 올바를 데이터를 입력했는지 유효성을 체크해주는 것.

Client Validation

react form validation은 client validation check에 해당

1. 사용자에게 편리함을 제공하기 위함

클라이언트 측에서 유효성 체크를 하지 않을 경우, 데이터가 서버까지 다녀온 뒤에야 잘못된 데이터임을 알 수 있다. 시간이 오래걸려 사용자도 불편함을 겪고, 서버도 너무 많이 일을 혼자 하게된다.

 

2. 이상한 데이터가 들어와 공격당하는 일이 없도록 하기 위한 보안조치

사용자가 의도적으로 이상한 데이터를 넣어 공격을 하는 것을 맊을 수 있다. 하지만 클라이언트 유효성 체크만으로는 안전하지 않기 때문에 반드시 서버에서도 유효성 체크를 해주어야 한다.

 

React Form Validation library

라이브러리 도입 전, 라이브러리 설치를 정당화 할 만큼 form을 많이 / 복잡하게 사용하고 있는지 확인

React 에서 form 사용 시 라이브러리를 사용하지 않게 될 경우, 많은 보일러플레이트 코드 발생

  • 유저 입력 값의 상태 관리 (state, onChange)
  • 유효성 검사
  • 오류 메시지
  • 폼 제출 다루기

React 에서 가장 많이 사용하는 form validation library는 formik과 react hook form 이다.

 

Formik

특징

  • 가장 많이 사용되는 라이브러리
  • 사용하기 쉬움
  • provider 방식으로, form내에 있는 모든 컴포넌트들이 동일한 상태를 공유한다.
  • re-rendering 많이 발생
  • 유효성 체크를 위해, yup 라이브러리와 함께 많이 사용

단점

  • 복잡한 form을 다루기 어렵다
  • 특정 state만 watch할 수 없고 전체를 업데이트
  • 불필요한 re-redering 발생

React Hook Form

특징

  • Formik 다음으로 많이 사용되는 라이브러리
  • 사용하기 쉬움
  • 타입스크립트로 작성된 라이브러리 -> 타입스크립트 기본 제공
  • 불필요한 re-rendering을 피하기 위해 uncontrolled components를 사용하도록 설계
  • re-render 최소화
  • 적은 코드, 적은 용량, 빠른 성능

Formik VS React Hook Form 

사용량을 봤을 땐, Formik 이 확연히 높다.

하지만 표로 비교해 봤을 때, React Hook Form의 사이즈, 이슈가 훨씬 적고 특히 dependency가 formik이 9개인 반면 react hook form은 0개인 것이 큰 장점이다.

dependency는 위 그림과 같다.

Formik 사용법

import { Formik } from "formik";
const ValidatedLoginForm = () => (
 <Formik
   initialValues={{ email: "", password: "" }}
   ...
 >
 ...
 </Formik>
);

[Formik]

  • Formik is a component that helps you with building forms. 

[initialValues]

  • form의 초기화 값. 반드시 지정해주어야 한다.

 

const ValidatedLoginForm = () => (
 <Formik
   ..
   onSubmit={(values, { setSubmitting }) => {
     setTimeout(() => {
       console.log("Logging in", values);
       setSubmitting(false);
     }, 500);
   }}
   ..
 >
   ..
 </Formik>
);

[onSubmit]

  • form submission handler.

[values]

  • form에서 공유되는 상태 값. 

[setSubmitting]

  • You would call it with setSubmitting(false) in your onSubmit handler to finish the cycle.
  • onSubmit이 비동기일 경우, 자동으로 false로 지정해주어서 setSubmit(false)를 해주지 않아도 되지만, 동기일 경우에는 반드시 setSubmit(false)를 해주어야 한다.

 

import * as Yup from "yup";

const ValidatedLoginForm = () => (
 <Formik
   ..
   validationSchema={Yup.object().shape({
     email: Yup.string().email().required("Required"),
     password: Yup.string()
       .required("No password provided.")
       .min(8, "Password is too short - should be 8 chars minimum.")
       .matches(/(?=.*[0-9])/, "Password must contain a number.")
   })}
 >
   ..
 </Formik>
);

[validationSchema]

  • yup 스키마를 리턴. 유효성 검증에 사용된다.

[yup]

  • form validation을 위한 라이브러리.

 

const ValidatedLoginForm = () => (
 <Formik ...>
   {(props) => {
     const {
       values,		// form에서 공유되는 상태 값
       touched, 	// 사용자의 필드 방문/터치 여부 (boolean)
       errors, 		// form validation 에러
       isSubmitting,	// form 제출 상태 (boolean)
       handleChange,	// input change event handler. values[key] 를 업데이트
       handleBlur,	// onBlur event handler
       handleSubmit	// submit handler
     } = props;
     return (
       <form onSubmit={handleSubmit}>
         <input
           name="email"
           value={values.email}
           onChange={handleChange}
           onBlur={handleBlur}
         />
         {errors.email && touched.email && (
           <div className="input-feedback">{errors.email}</div>
         )}
...
	    // 제출 버튼을 두 번 클릭하여 오류발생시키는 일이 없게 하기 위함.
         <button type="submit" disabled={isSubmitting}> 
           Login
         </button>
       </form>
     );
   }}
 </Formik>
);

 

Formik 예제 코드

Formik Component

useFormik

 

React Hook Form 사용법

import { useForm } from "react-hook-form";

const LoginForm = () => {
 const {
   register,
   handleSubmit,
   formState: { errors }
 } = useForm();
 const onSubmit = (data) => console.log(data);
 const onError = (error) => console.log(error);
 return (
   <form onSubmit={handleSubmit(onSubmit, onError)}>
     <input
       {...register("email", {
         required: "Required",
         pattern: {
           value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
           message: "invalid email address"
         }
       })}
     />
	...
     {errors.email && errors.email.message}
     <button type="submit">Submit</button>
   </form>
 );
};

[register]

  • input 또는 select box를 등록하고 유효성 규칙을 적용시킨다.
  • input 에서 값을 불러오기 위한 함수
  • 옵션을 사용해 유효성 검사도 쉽게 할 수 있다.

[handleSubmit]

  • submit handler
  • 함수를 인자로 받으며, data 인자를 넘겨준다.

[formState]

  • form state에 대한 정보들을 가지고 있다.

[errors]

  • form validation 에러

[onSubmit]

  • form data

[onError]

  • form validation 에러

React Hook Form 예제 코드

 

세미나를 하고 기록해보았다.

개인적으로는 React Hook Form이 좀 더 마음에 든다.