
Zod 공식 홈페이지에서는 정적 유형 추론을 통한 타입스크립트 우선 스키마 유효성 검사 라고 소개하고있다.
쉽게 말하자면, 타입도 만들고, 그 타입에 맞는 값인지 검사도 한 번에 해주는 도구다.
z.string().trim().email().min(1, { message: '이메일을 입력해주세요.' }),
런타임에서도 검증 가능
실제 입력되는 데이터에 대해서 실시간으로 검사한다.
타입과 유효성 검사를 동시에 처리
한 번의 코드로 타입 선언 + 값 검증 → 중복 X
react-hook-form과 연동성
zodResolver를 통해 Zod 스키마를 react-hook-form의 유효성 검사기로 연결
타입 검증과 폼 검증을 한 번에 처리 가능
잘못된 입력값에 대해 자동으로 에러 메시지 처리 가능
Zod 설치
npm install zod
react-hook-form과 같이 사용할 계획이라면 resolver도 설치
npm install @hookform/resolvers
데이터의 구조와 규칙을 미리 정의해 놓은 설계도
데이터는 어떤 모양이고, 어떤 값들이 와야 하는지를 정해놓은 약속
Zod는 Zod에서 제공해주는 z라는 객체를 가지고 조작하게된다. z안에는 다양한 메서드가 포함되어있다.
아래 코드처럼 z.object를 통해 스키마를 만들고 설정할 수 있다.
아래는 email, password레 대한 스키마를 만든 예시다.
email은 string이며, email형식을 갖춰야한다고 설정했다.
password는 string이며, 최소8글자이상을 입력해야한다 8글자가 되기 전까지 '비밀번호는 최소8자 이상으로 입력해주세요.'라는 문구가 나오게 설정했다.
이와 같이 직관적은 메서드들을 사용해 간단하게 유효성 검사를 할 수 있다. 매우 간편하다.
const signUpSchema = z.object({
email: z.string().email()
password: z.string().min(8, { message: '비밀번호는 최소8자 이상으로 입력해주세요.' }),
});
나는 react-hook-form과 함께 사용할 것이기 때문에 resolver를 사용할 것이다.
외부 유효성 라이브러리(Zod)를 사용할 경우, 해당 라이브러리로 유효성 검사를 처리하도록 하려면 resolver를 설정해줘야한다.
useForm 옵션에 resolver라는 옵션을 넣고 zodResolvers라는 메서드를 사용해 react-hook-form과 함께 사용할 수 있다.
mode: 'onChange'는 input 값을 수정할 때마다 유효성 검사를 실행하겠다는 옵션이다. UX적으로 입력할 때마다 상황에 맞는 안내문구를 보여주면 더 빠르게 폼을 완성시킬 수 있다고 생각해서 옵션을 사용했다.단, 스키마에 설정한 이름과 register에 설정한 이름이 같아야만 적용된다.
const { register, handleSubmit, formState } = useForm({
mode: 'onChange',
resolver: zodResolver(signUpSchema),
});
input 값을 수정할 때마다 유효성 검사를 실행하겠다는 옵션을 설정했었다.
이를 통해 input 값을 수정할 때마다 안내 문구를 렌더링시킬 수 있다.
register에 입력한 이름 ...register('nickname')과 스키마에 설정한 이름 z.object({nickname: z.string()}) 이 같아야만 적용된다.
{formState.errors.nickname && <span>{formState.errors.nickname.message} 코드는 formState객체를 이용해 nickname 유효성 검사에 만족하지 못할 때 안내 문구를 보여줄 수 있다. 이와 같이 email과 password에도 동일하게 적용가능하다.
<div>
<label htmlFor='nickname'>닉네임</label>
<input type='text' id='nickname' placeholder='헤엄치는 수달' {...register('nickname')} />
{formState.errors.nickname && <span>{formState.errors.nickname.message as string}</span>}
</div>