Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- IntersectionObserver
- bootstrap
- SQL
- REACT
- Github Pages
- http
- JavaScript
- W
- Boostrap
- supabase
- til
- db
- 배포
- data
- firestoredatabase
- this
- Fetch
- useEffect
- Cloud
- HTML
- github
- TMDB
- API
- nosql
- Protocol
- jQuery
- url
- web
- Database
- CSS
Archives
- Today
- Total
072DATA
react-hook-form으로 폼 유효성 검사 구현 본문
사용자가 여러 챌린지를 고르고 각 챌린지마다 최소 하나의
세부 옵션을 골라야 하는 폼을 만들어야 했다
예를 들어 '파일 정리'를 골랐으면
"불필요한 파일 삭제", "폴더 정리" 중에 하나는 꼭 선택해야 했다.
해결 과정
폼에서 다룰 데이터 타입을 먼저 정의했다
interface ChallengeFormInputs {
content: string;
images?: FileList;
selectedOptions: Record<string, string[]> // 챌린지별로 선택된 옵션들
}
const {
register,
handleSubmit,
formState: { errors },
setError,
clearErrors
} = useForm<ChallengeFormInputs>();
react-hook-form을 설정하고,
폼을 제출할 때는 이렇게 유효성 검사를 했다 ( 주석 참고)
const onSubmit = async (data: ChallengeFormInputs) => {
try {
// 선택된 챌린지 중에서 옵션을 하나도 안 고른 챌린지 찾기
const unselectedChallenges = selectedChallenges.filter((challengeId) => {
return !selectedOptions[challengeId] || selectedOptions[challengeId].length === 0;
});
if (unselectedChallenges.length > 0) {
// 옵션 안 고른 챌린지들 이름 가져오기
const challengeNames = unselectedChallenges
.map((id) => CHALLENGES.find((c) => c.id === id)?.label)
.filter(Boolean)
.join(", ");
// 에러 설정
setError("selectedOptions", {
type: "validate",
message: `${challengeNames}의 상세 항목을 선택해주세요`
});
return;
}
// 유효성 검사 통과하면 제출
await challengeMutation.mutateAsync({
// 제출할 데이터
});
} catch (error) {
// 에러 처리
}
};
옵션을 선택할 때마다 에러 상태도 관리해줬다
const handleOptionToggle = (challengeId: string, optionId: string) => {
setSelectedOptions((prev) => {
//이전 로직...
// 모든 챌린지에 옵션이 잘 선택됐는지 확인하고
const allOptionsSelected = selectedChallenges.every((id) => {
const options = updatedOptions[id] || [];
return options.length > 0;
});
// 다 선택됐으면 에러 초기화 시키기
if (allOptionsSelected) {
clearErrors("selectedOptions");
}
return updatedOptions;
});
};
이렇게 로직을 구현함으로서
- 챌린지는 골랐는데 세부 옵션을 안 고르면 어떤 챌린지의 옵션을 골라야 하는지 알려준다
- 필요한 옵션을 다 고르면 자동으로 에러가 사라진다
- react-hook-form으로 복잡한 폼 상태와 유효성 검사를 깔끔하게 처리할 수 있었다
단순히 "이 필드는 필수입니다" 같은 기본적인 검사가 아니라
실제 서비스에서 필요한 복잡한 유효성 검사도 react-hook-form으로 잘 구현할 수 있다는 걸 배웠다.
'FrontEnd > Next.js' 카테고리의 다른 글
친환경 스토어 지도 개발 로그 2편 ( 카카오맵 불러오기, 마커와 인포 윈도우 생성 ) (0) | 2024.11.12 |
---|---|
친환경 스토어 지도 개발 로그 1편 ( 데이터 분석 및 삽입 ) (1) | 2024.11.09 |
다중으로 이미지 업로드 구현하기 ( supabase Storage ) (0) | 2024.10.29 |
OOTW 프로젝트 - 글 작성 구현하기 ( 이미지 업로드 ) (2) | 2024.10.18 |
next.js supabase 이미지 업로드 (0) | 2024.10.15 |