-
[React validation] Zod vs Yup 비교 / react-hook-form 같이 쓰기front-end/React 2023. 6. 5. 22:49
이번에 Next.js13로 사이드플젝 및 포트플리오 진행중에 Form의 라이브러리는 react-hook-form이 적합한거 같아서
react-hook-form으로 form 관리를 하고있는데 , 이제 validtaiton의 라이브러리를 무엇을 쓸지 정하는 와중에 Zod와 Yup이
가장 대중적인거같아서 두가지를 한번 비교를 해보려고 합니다.
우선 라이브러리 없이 리액트에서 여러가지 인풋을 관리한다면 꽤 귀찮은 작업일것입니다.
그래서 이번 비교 글도 react-hook-form 라이브러리를 이용하면서 zod 와 yup을 비교 해보려고 합니다.
예시 코드로 간단한 Form 컴포넌트를 하나 생성 해주었습니다.


앞서 말하지만 한가지 state 로 관리 한다고 해도 외부 라이브러리를 사용안하고 useState와 onChange 그리고 validation 체크까지는 귀찮은 작업일것입니다 .
한두개 인풋이면 모를까 인풋이 10개가 넘어가면 관리도 힘들고 코드도 길어지겠죠
혹시 한가지 state로 여러개의 인풋 관리하시는분들은
https://react.vlpt.us/basic/09-multiple-inputs.html 이걸 먼저 보고 오는게 좋을것같습니다.
위 예시 코드에 react-hook-form 을 바로 적용 해보겠습니다.
On terminal : npm install react-hook-form

맨 첫번째 인풋 register(...text) 가 아니라 fullName 입니다 참고해주세요.! React-hook-form에선 register , handleSubmit 두개가 중요한 것들이니 이 두가지에 대해선 꼭 알아야 진행이 수월합니다.
React-hook-form 의 자세한 기능 및 설명은 따로 포스팅을 할 예정입니다.
간단하게 두가지 기능을 설명드리면,
React-hook-form
regitser
폼 필드를 React Hook Form에 등록하는 함수입니다. 이 함수는 입력 요소의 ref 속성과 연결하여 폼 데이터 수집 및 유효성 검사에 사용됩니다. register는 필드 유효성 검사 규칙을 지정할 필요 없이 자동으로 등록됩니다.
handleSubmit
폼의 제출을 처리하는 함수입니다. 이 함수는 제출 이벤트(일반적으로 <form> 요소의 onSubmit 핸들러)에 연결되어 실행됩니다. handleSubmit은 내부적으로 폼 데이터를 수집하고, 데이터 유효성 검사를 수행한 후, 유효한 데이터일 경우 등록한 onSubmit 콜백 함수를 호출합니다.
아래의 필드를 입력하고 콘솔창에 찍어보면 register 로 등록한 input 의값들이 객체로 출력되는것을 볼수있습니다.
여기서 "이름 fullName" 필드는 일부로 입력하지않고 , 제출을 했는데도 에러없이 콘솔에 잘 출력 되는걸 볼수있습니다.


사실 뭐 fullName 의 value 값을 체크 해서 제출을 막을 수 있습니다.
하지만 yup 이나 zod 같은 라이브러리를 이용하면 좀더 복잡한 유효성 검사 규칙을 쉽게 정의하고 관리할 수 있습니다.
이는 코드의 재사용성과 가독성을 향상시키며, 개발자가 더 강력하고 정확한 폼 유효성 검사를 할 수 있습니다.
Yup
먼저 yup 을 통해서 validation 추가를 해보겠습니다.
yup npm reference : https://www.npmjs.com/package/yup
yup
Dead simple Object schema validation. Latest version: 1.2.0, last published: 11 days ago. Start using yup in your project by running `npm i yup`. There are 4555 other projects in the npm registry using yup.
www.npmjs.com
On terminal: npm install yup , npm install @hookform/resolvers

최상단에 import * as yup from 'yup' 추가해줍니다 .
코드에 validation을 정의 해주는schma를 추가해줍니다.
yup.object().shape()
Yup 라이브러리에서 제공하는 객체 유효성 검사 규칙을 정의하는 메서드입니다. 이 메서드를 사용하여 객체의 속성과 해당 속성에 대한 유효성 검사 규칙을 정의할 수 있습니다.shape() 메서드는 중첩된 객체 구조에서 유효성 검사를 수행하기 위해 사용됩니다. 예를 들어, 폼이나 데이터 객체에 여러 속성이 있고 각 속성마다 다른 유효성 검사 규칙을 적용하려는 경우 유용합니다.
전달되는 인자는 객체 형태로 정의됩니다. 각 속성은 해당 속성의 이름과 그에 대한 유효성 검사 규칙을 포함하는 Yup 스키마 객체입니다. 이러한 규칙을 사용하여 속성의 유효성을 검사하고 필요한 경우 오류 메시지를 설정할 수 있습니다.
- fullName: yup.string().required('이름 확인해주세요.')
-fullName 필드는 문자열이어야 하며, 필수값이어야 합니다. 만약 값이 비어있을 경우 "이름 확인해주세요."라는 에러 메시지가 나타납니다. - email: yup.string().email("이메일 형식에 맞게써주세요.").required('이메일은 필수값입니다.')
-email 필드는 문자열이어야 하며, 이메일 형식에 맞아야 합니다. 이메일 형식에 맞지 않을 경우 "이메일 형식에 맞게써주세요."라는 에러 메시지가 나타납니다. 또한, 필수값이기 때문에 값이 비어있을 경우 "이메일은 필수값입니다."라는 에러 메시지가 나타납니다. - age: yup.number().positive().integer().min(10 , "나이는 10 이상여야합니다").required("나이 필드를 입력해주세요.")
-age 필드는 숫자이어야 하며, 양수이고 정수이어야 합니다. 최소값으로 10을 지정하였으며, 값이 10 미만인 경우 "나이는 10 이상이어야합니다"라는 에러 메시지가 나타납니다. 또한, 필수값이기 때문에 값이 비어있을 경우 "나이 필드를 입력해주세요."라는 에러 메시지가 나타납니다. - password: yup.string().min(4,"비밀번호는 4자 이상여야합니다").max(10 ,"비밀번호는 10자 이하이여야합니다").required('비밀번호는 4~10자 사이여야 합니다.')
-yup.string().min(4,"비밀번호는 4자 이상여야합니다").max(10 ,"비밀번호는 10자 이하이여야합니다").required('비밀번호는 4~10자 사이여야 합니다.') - passwordCheck: yup.string().oneOf([yup.ref('password'), null as any], '비밀번호가 일치하지 않습니다')
-passwordCheck 필드는 문자열이어야 하며, password 필드와 일치해야 합니다. 일치하지 않을 경우 "비밀번호가 일치하지 않습니다"라는 에러 메시지가 나타납니다.
이러한 유효성 검사 규칙을 정의하면 사용자가 폼을 제출할 때, 각 필드에 대해 해당 규칙을 검사하여 유효성 여부를 판단합니다. 만약 어떤 필드가 규칙에 맞지 않는다면, 해당 필드에 대한 오류 메시지가 표시됩니다. 이를 통해 사용자가 유효하지 않은 데이터를 입력할 경우 미리 방지하고, 정확한 데이터를 수집할 수 있습니다.
사실 코드만 봐도 가독성이 굉장히 좋은편인것같습니다. 어떤 값을 필수로 제출 해야하는지 , 어떤양식으로 써야하는지 눈으로 봐도 대강 알수 있는거같죠?

FYI:required에 validation 메세지를 넣지않으면 default값이 화면에 보입니다.
yupResolver(schema): yup 유효성 검사 스키마를 resolver로 사용하여 폼의 유효성 검사 규칙을 설정합니다. 이렇게 설정된 규칙은 react-hook-form이 폼의 입력값을 검증할 때 적용됩니다. yupResolver 함수를 사용하여 yup 스키마를 resolver로 전달하여 유효성 검사를 수행합니다.
resolver 엔 zodResolver , joinResolver 그리고 custom resolver 도 구현할 수 있습니다.

submit을 할때 유효성 검사를 한 뒤 조건에 안맞는 validation 문구를 이런식으로 보여줄 수 있습니다.
Zod
zod reference : https://zod.dev/GitHub - colinhacks/zod: TypeScript-first schema validation with static type inference
TypeScript-first schema validation with static type inference - GitHub - colinhacks/zod: TypeScript-first schema validation with static type inference
github.com
On terminal: npm install zod , npm install @hookform/resolvers
zod 라고 해서 yup과 아주 다르진 않습니다.크게 다른것은 타입스크립트와 함께 적용을 잘 할 수 있습니다.
zod 는 아래와 같은 장점이 있습니다.
- API 디자인 및 사용성: Zod는 TypeScript를 고려하여 설계된 API를 가지고 있으며, 정적 타입 체크와 함께 더 강력한 유형 검사 기능을 제공합니다. 반면에 Yup은 기본적으로 JavaScript에 초점을 맞추어 설계되었으며, 더 많은 유연성을 제공합니다.
- 타입스크립트 지원: Zod는 타입스크립트와 완벽하게 통합되어 있으며, 타입 안정성과 코드 완성 기능을 갖추고 있습니다. Yup은 타입스크립트를 지원하지만, 일부 타입 추론이 어려울 수 있습니다.
- 코드 베이스 크기: Zod은 상대적으로 작은 패키지 크기를 가지고 있으며, 필요한 기능에 대한 최소한의 코드만 포함합니다. Yup은 더 큰 패키지 크기를 가지고 있지만, 기능이 풍부하고 다양한 검증 방법을 제공합니다.
아래는 바로 zod를 적용 한 예시 입니다.
yup이랑 별반 다를게 없어 보이죠?
크게 차이점은
필수항목은 yup required 대신 zod optional 의 함수로 정의 할수있습니다.
opitonal 함수를 이용하면 유효성 검사 함수는 사용할 수 없습니다.
opiton().min(5).max(10) 이런식으로 체이닝을 할 경우 에러가 발생합니다.
비밀번호 검사하는 스키마 쪽을 보시면 yup에 비해서 간단하게 비교 할 수 있습니다.
이런식으로 체이닝으로도 검사 할 수 있습니다.
const schema = z .string() .refine((value) => value.length >= 5, "문자열은 5글자 이상이어야 합니다.") .refine((value) => value.length <= 10, "문자열은 10글자 이하여야 합니다.");위의 예제에서는 문자열의 길이가 5글자 이상이고 10글자 이하여야 한다는 조건을 추가로 정의하였습니다. 조건을 만족하지 않을 경우 각각에 대한 에러 메시지가 반환됩니다.


리액트에서 개발을 한다면 , 타입스키릅트는 거의 필수이기 때문에 , 타입스크립트와 시너지가 좋은 zod가 요새 뜨고 있는 것 같습니다.
지금까지 zod와 yup을 비교하는 포스팅을 작성해봤는데 , 마무리 하며 간단하게 zod 와 yup 주요 차이점을 말씀 드리자면
- TypeScript 지원: Zod은 TypeScript에 대한 네이티브 지원을 제공합니다. 따라서 타입 안전성을 보장하면서 유효성 검사를 수행할 수 있습니다. Yup은 TypeScript에서도 사용할 수 있지만, 별도의 타입 정의 파일이 필요합니다.
- 문법 및 체이닝: Zod은 체인 메서드를 사용하여 유효성 검사 스키마를 작성합니다. 이를 통해 코드를 읽기 쉽고 간결하게 작성할 수 있습니다. Yup은 객체 빌더 패턴을 사용하여 유효성 검사 스키마를 작성합니다.
- 라이브러리 크기: Zod은 경량화된 라이브러리로 알려져 있으며, 번들 크기에 더 적은 영향을 줍니다. Yup은 상대적으로 더 많은 기능을 제공하는 대신 크기가 더 큰 라이브러리입니다.
- 생태계와 커뮤니티: Yup은 더 오래되고 널리 사용되는 라이브러리이므로 생태계와 커뮤니티가 더욱 발전되어 있습니다. 반면 Zod은 상대적으로 새로운 라이브러리이지만, TypeScript 커뮤니티에서 인기가 높아지고 있습니다.
TypeScript를 사용하고 타입 안정성을 강조한다면 Zod이 더 적합할 수 있습니다. 반면 JavaScript와 TypeScript를 모두 지원하고 더 큰 생태계와 커뮤니티가 필요하다면 Yup을 고려해볼 수 있겠습니다!
개인 프로젝트 및 포트폴리오에 react-hook-form 과 zod를 통해서 form 을 관리 할 예정이니 , 포트폴리오 관련 게시글 올릴때 더욱 자세히 올려보겠습니다~!
'front-end > React' 카테고리의 다른 글
[React] HOC (고차 컴포넌트, Higher-Order Component) (0) 2023.08.18 [React]When to use UseMemo and useCallback (feat:memo) / useCallback 편 (0) 2023.08.09 [React] React에서 흔히 발생하는 실수 4가지 (1) 2023.05.17 [React] React query 개념 및 예제 (0) 2023.04.28 [React-Router V6] useOutletContext (0) 2023.01.13 - fullName: yup.string().required('이름 확인해주세요.')