보통 회윈가입 form 을 제출하기 전에 사용자가 입력한 데이터가 사이트에서 요구하는 조건을 만족하는지(유효성) 검사를 실시한다. 요구되는 사항 자체가 단순한 경우에는 바닐라 자바스크립트나 HTML form 을 구성하는 요소가 내부적으로 가지는 속성으로 간단하게 처리할 수 있지만, 요구되는 사항이 복잡한 경우에는 이 모든 것을 일일이 다루기에는 코드가 너무 길어져서 가독성이나 재사용성 등에 있어서 그리 좋은 처리는 아닐 수 있다.
따라서 언제든지 사항에 따라 활용할 수 있도록 오늘은 강력하면서도 단순하게 유효성을 체크할 수 있는 유효성 검사 라이브러리에 대한 간략한 소개와 사이트 링크에 대한 정보를 정리해두고자 한다.
React Hook Form
React Hook Form은 React Hook을 사용하여 폼 관리와 유효성 검사를 간단하게 실시할 수 있는 라이브러리 로 소개된다. 따라서 훅을 기반으로 한 내장된 유효성 검사 기능을 제공한다.
npm 사이트에서 확인해보면, 주간 다운로드 횟수도 많은 편이며 유지보수가 꾸준히 잘 되고 있는 것을 볼 수 있다.
https://www.npmjs.com/package/react-hook-form
https://react-hook-form.com/get-started
Formik
Formik은 React Hook Form과 유사한 라이브러리다. React Hook을 사용하여 폼 관리와 유효성 검사를 간단하게 할 수 있으며, 당연한 말이지만 내장된 유효성 검사 기능을 제공한다.
React Hook Form 보다는 아니지만, 주간 다운로드 횟수와 유지보수가 잘 되고 있음을 볼 수 있다.
https://www.npmjs.com/package/formik
https://formik.org/docs/overview
아래는 유효성 검사 예시 코드이다. Formik 라는 컴포넌트 내부에서 함수를 호출하는 특이한 방식으로 작성되어 있다. 자세한 설명과 예시는 위 공식 문서에서 확인하자.
import React from 'react';
import { Formik } from 'formik';
const Basic = () => (
<div>
<h1>Anywhere in your app!</h1>
<Formik
initialValues={{ email: '', password: '' }} // 초깃값
validate={values => { // 검증
const errors = {};
// 이메일이 없을 경우 erros 객체에 email : Required 추가
if (!values.email) {
errors.email = 'Required';
// 이메일이 존재하여 유효성 검사를 실시하였으나, 통과 못 하는 경우
// email : Invalid email address 를 errors 객체에 추가
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
// 에러 객체 반환
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
/* and other goodies */
}) => (
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
onChange={handleChange}
onBlur={handleBlur}
value={values.email}
/>
{errors.email && touched.email && errors.email}
<input
type="password"
name="password"
onChange={handleChange}
onBlur={handleBlur}
value={values.password}
/>
{errors.password && touched.password && errors.password}
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</form>
)}
</Formik>
</div>
);
export default Basic;
Yup
Yup은 객체의 유효성 검사를 위한 라이브러리다. Joi 와 유사하다. 앞서 유효성 검사 라이브러리에 비해 더 높은 사용량 보이고 있다.
https://www.npmjs.com/package/yup
아래 예시 코드만 보아도 앞서 Form 라이브러리에 비해 사용 방법이 아주 단순한 것을 알 수 있다. 단, 서로 사용하는 목적이나 범위 차이가 있기 때문에, 필요에 따라 앞서 라이브러리와 혼합해서 사용할 수 있다.
import { object, string, number, date, InferType } from 'yup';
let userSchema = object({
name: string().required(), // 문자, 필수
age: number().required().positive().integer(), // 숫자, 필수, 양수, 정수
email: string().email(), // 문자, 이메일
website: string().url().nullable(), // 문자, 주소, null 허용
createdOn: date().default(() => new Date()), // 날짜, 기본값은 new Date()
});
// 구문분석 및 유효성 검사 실시
// 앞서 userSchema 에 fetchUser() 에서 반환된 데이터가 전달되어 유효성 검사를 실시
// 이 검사를 통과 해야지만, user 에 데이터가 반환되고, 실패하면 에러가 반환된다.
const user = await userSchema.validate(await fetchUser());
type User = InferType<typeof userSchema>;
/* {
name: string;
age: number;
email?: string | undefined
website?: string | null | undefined
createdOn: Date
}*/
Joi
Joi는 Yup과 유사하다 객체의 유효성 검사를 위한 라이브러리로 주로 쓰인다. Yup 과 비교하면 압도적으로 자주 쓰이는 것을 볼 수 있는데, 어떤 차이가 있을지 나중에 한 번 써봐야 겠다.
라이선스가 처음 보는 것이라 검색해본 링크를 달아둔다.
https://www.olis.or.kr/license/Detailselect.do?lId=1092&mapCode=010003&lType=osi
이것은 공식 문서 주소
아래는 사용 예시인데 Yup 과 아주 유사하다.
const Joi = require('joi');
const schema = Joi.object({
username: Joi.string()
.alphanum() // 알파벳과 숫자만 허용
.min(3) // 최소 3자
.max(30) // 최대 30자
.required(), // 필수
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')), // 정규식 패턴과 일치해야
repeat_password: Joi.ref('password'), // password 유효성 검사 규착을 참조
access_token: [
Joi.string(), // 문자
Joi.number() // 숫자
],
birth_year: Joi.number() // 숫자
.integer() // 정수
.min(1900) // 최소 1990
.max(2013), // 최대 2013
email: Joi.string()
.email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
.with('username', 'birth_year') // 두 속성이 서로 일치해야
.xor('password', 'access_token') // 두 속성 중 하나는 선택해야
.with('password', 'repeat_password'); // 두 속성이 서로 일치해야
schema.validate({ username: 'abc', birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }
// username 은 required 로 지정했는데 아무런 값도 정말 하지 않아서 에러 띄움
schema.validate({});
// -> { value: {}, error: '"username" is required' }
// Also -
try {
const value = await schema.validateAsync({ username: 'abc', birth_year: 1994 });
}
catch (err) { }
참고를 위해 현재 보이는 유효성 검사 규칙에 대한 설명만 정리해보았다.
.alphanum(): 알파벳과 숫자만 허용
.min(): 최소 길이를 지정
.max(): 최대 길이를 지정
.required(): 필수 항목을 지정
.pattern(): 정규식을 사용하여 유효성 검사를 수행
.ref(): 다른 속성의 유효성 검사를 참조
.array(): 배열 유효성 검사를 정의
.integer(): 정수만 허용
.min(): 최소 값을 지정
.max(): 최대 값을 지정
.email(): 유효한 이메일 주소만 허용
.with(): 두 속성의 값이 서로 일치해야 함
.xor(): 두 속성 중 하나만 선택해야 함
'리액트' 카테고리의 다른 글
[React] useId | 고유한 id 값을 생성해주는 리액트 훅 (1) | 2024.02.05 |
---|---|
[개인 정리]프론트엔드 상태관리 라이브러리 비교(redux, recoil, zustand) (0) | 2023.12.27 |
[react ] Jotai, Recoil, Zustand, Valtio | Jotai (1) (1) | 2023.12.10 |
[React.v18 ] useTransition 과 논블로킹 (4) | 2023.11.26 |
[react] 리액트에서 key 의 용도와 중요성 (0) | 2023.11.10 |