이번 프로젝트에서, 아래와 같이
카테고리 명, 카테고리 썸네일, 카테고리에 넣을 영상 입력값에 대한 유효성 검사를 수행하기 위해
zod와 react-hook-form을 사용하려 한다.

우선, 아래의 명령어로 라이브러리를 설치한다.
npm install react-hook-form @hookform/resolvers zod
필요한 라이브러리를 import 한다
import { useForm, Controller } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
입력 폼에 대한 어떤 값에 검사하는 조건과 메시지를 설정하는 스키마를 작성한다.
이때 기존에 작성하던 파일은 tsx파일로, Page를 담당하고 있었다.
따라서 단일 책임 원칙에 따라
src/schema/categorySchema.ts 파일을 생성하여 선언하고, import하도록 하였다.
import { z } from 'zod';
const categorySchema = z.object({
categoryName: z.string().min(1, { message: '카테고리 명을 입력해주세요' }),
imgFile: z
.string()
.min(1, { message: '썸네일을 선택해주세요' })
.refine(
value => {
const validPrefixes = [
'data:image/jpg;base64,',
'data:image/jpeg;base64,',
'data:image/png;base64,',
];
return validPrefixes.some(prefix => value.startsWith(prefix));
},
{
message: 'jpg, jpeg, png 파일만 허용됩니다.',
},
),
videos: z.string().min(1, { message: '최소 하나의 동영상을 선택해주세요' }),
});
export { categorySchema };
5 changes: 4 additions & 1 deletion5
tsconfig.json
다음은 useForm을 사용하여 폼을 관리한다.
type CheckInput = {
categoryName: string;
imgFile: string;
videos: string;
};
const { control, formState: { errors }, handleSubmit, setValue, clearErrors } = useForm<CheckInput>({
resolver: zodResolver(schema),
defaultValues: {
categoryName: '',
imgFile: '',
videos: '',
}
});
여기서 중요 포인트는 다음과 같다.
1. contorl : 폼의 상태와 입력 요소를 연결하는데 사용한다.
2. setValue : 특정 입력 필드의 값을 설정하는데 사용
3. resolver : zodResolver는 스키마 기반의 유효성 검사를 실행
작성한 스키마를 바탕으로 react-hook-form을 사용하여 입력 폼을 작성한다.
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="categoryName"
control={control}
render={({ field }) => (
<LabelInput
title="카테고리 명"
placeholder="카테고리 명을 입력해주세요."
onChange={(e) => {
field.onChange(e);
if (e.target.value) {
clearErrors('categoryName');
}
}}
value={field.value}
/>
)}
/>
{errors.categoryName && (
<p className="text-sm text-red-500">{errors.categoryName.message}</p>
)}
여기서 위에서 설정한 입력값을 체크한다. {errors.categoryName}으로..
여기서, 다른 곳과 다른 점은 Contorller를 사용한 것이다.
그 이유는 text를 입력받는데, onChange와의 충돌로 값이 입력되었음에도 에러메시지가 사라지지 않기 때문이다.
- Controller: 커스텀 입력 컴포넌트를 사용할 수 있게 함
- name: 폼 상태에서 관리할 필드의 이름을 지정, 여기서는 "categoryName"이라는 이름을 가진 필드를 관리
- control: 폼 상태와 입력 필드를 연결
- render: Controller가 렌더링할 컴포넌트를 정의 여기서 field 객체가 파라미터로 전달되며, 이 객체에는 입력 필드를 제어하는 데 필요한 여러 메서드와 프로퍼티가 포함되어 있다.
- LabelInput: 이 컴포넌트는 title과 placeholder 속성을 통해 사용자에게 입력할 내용을 안내한다
- onChange: 사용자가 입력 필드의 값을 변경할 때 호출되는 함수이다. 여기서는 field.onChange(e)를 호출하여 React Hook Form에 입력값을 전달. 입력값이 존재할 경우 clearErrors('categoryName')를 호출하여 해당 필드의 오류 메시지를 지운다.
- value: field.value를 사용하여 현재 입력 필드의 값을 설정하는데 이는 Controller가 관리하는 폼 상태와 동기화된다.


'패스트캠퍼스 데브캠프' 카테고리의 다른 글
토이3 프로젝트 - 작성한 코드 복기 (1) - 프로젝트 정리 (0) | 2025.01.17 |
---|---|
김민태의 데브캠프 2기 - 실시간 강의(면접 관련) (0) | 2025.01.14 |
김민태의 데브캠프 2기 - 실시간 강의 (01/09) (0) | 2025.01.09 |
토이프로젝트 3 - react-beautiful-dnd 라이브러리 사용법 (0) | 2025.01.08 |
React 스플래시 페이지 애니메이션 적용하기 (0) | 2025.01.02 |