072DATA

react-hook-form으로 폼 유효성 검사 구현 본문

FrontEnd/Next.js

react-hook-form으로 폼 유효성 검사 구현

0720 2024. 11. 4. 02:55

 

 

사용자가 여러 챌린지를 고르고 각 챌린지마다 최소 하나의

세부 옵션을 골라야 하는 폼을 만들어야 했다

예를 들어 '파일 정리'를 골랐으면

"불필요한 파일 삭제", "폴더 정리" 중에 하나는 꼭 선택해야 했다.

 

 

해결 과정

폼에서 다룰 데이터 타입을 먼저 정의했다

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으로 잘 구현할 수 있다는 걸 배웠다.