컴포넌트 인터페이스와 Props

2025. 4. 1. 18:56프론트엔드/REACT

728x90

1-1. React & React-Modal

  • React: 함수형 컴포넌트와 상태 관리를 위해 사용됩니다.
  • React-Modal: 모달창을 쉽게 구현할 수 있도록 도와주는 라이브러리입니다.
    • Modal.setAppElement('#root');
      → 접근성(Accessibility) 향상을 위해 모달이 열릴 때 스크린 리더가 앱의 나머지 부분을 무시하도록 루트 요소를 지정합니다.

1-2. CSS Modules

  • 파일을 TermsAgreementModal.module.css처럼 작성하면 클래스 이름이 네임스페이스화되어 충돌을 방지할 수 있습니다.
  • JSX에서는 import styles from './css/TermsAgreementModal.module.css';를 통해 CSS 모듈 객체를 받아, 각 클래스에 styles.클래스명 형식으로 접근합니다.

2. 컴포넌트 인터페이스와 Props

interface TermsAgreementModalProps {
  isOpen: boolean;
  onRequestClose: () => void;
  handleSubmit: () => void;
  registerCheck: {
    terms1: boolean;
    terms2: boolean;
  };
  setRegisterCheck: React.Dispatch<React.SetStateAction<{ terms1: boolean; terms2: boolean }>>;
}
  • isOpen: 모달이 열려있는지 여부를 boolean 값으로 받습니다.
  • onRequestClose: 모달을 닫기 위한 콜백 함수입니다.
  • handleSubmit: 약관 동의 후 최종 제출 처리 로직이 담긴 함수입니다.
  • registerCheck & setRegisterCheck: 약관 체크박스의 상태(terms1, terms2)를 관리하는 상태와 이를 업데이트하는 함수입니다.

4. 이벤트 핸들러 함수

4-1. 체크박스 상태 변경 (handleCheckboxChange)

const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  const { id, checked } = e.target;
  setRegisterCheck(prevState => ({ ...prevState, [id]: checked }));
};
  • 체크박스의 id와 체크 여부(checked)를 추출하여 registerCheck 상태를 업데이트합니다.
  • setRegisterCheck 함수는 기존 상태를 복사한 후, 해당 id에 해당하는 값을 변경합니다.

4-2. 제출 버튼 클릭 (handleSubmitClick)

const handleSubmitClick = () => {
  if (isSubmitting) return;
  if (!registerCheck.terms1 || !registerCheck.terms2) {
    alert('필수 항목을 모두 선택해주세요.');
    return;
  }
  onRequestClose();
  handleSubmit();
};
  • isSubmitting 체크: 제출 중복 실행을 막습니다.
  • 약관 체크 확인: terms1 또는 terms2가 체크되어 있지 않으면 경고창을 띄워 제출을 막습니다.
  • 약관이 모두 체크된 경우, 모달을 닫고 최종 제출 로직인 handleSubmit()를 실행합니다.

4-3. 개인정보 안내 모달 열고 닫기

const handleOpenAgreement = () => {
  setIsAgreementOpen(true);
};

const handleCloseAgreement = () => {
  setIsAgreementOpen(false);
};
  • handleOpenAgreement: 약관 이미지 클릭 시 개인정보 안내 모달을 열기 위해 상태를 true로 변경합니다.
  • handleCloseAgreement: 개인정보 안내 모달을 닫기 위해 상태를 false로 변경합니다.

5. JSX 구조 및 Modal 구성

5-1. 첫 번째 모달 (약관 동의 모달)

<Modal
  isOpen={isOpen}
  onRequestClose={onRequestClose}
  contentLabel="Terms Agreement Modal"
  className={styles.Modal}
  overlayClassName={styles.Overlay}
>
  <div className={styles["modal-contents"]}>
    <div className={styles["agreement-section"]}>
      <h3 className={styles.agreement_title}>약관에 동의해주세요</h3>
      <p className={styles.agreement_sub}>여러분의 소중한 개인정보를 잘 지켜 드릴게요</p>
      <ul className={styles.agreement_desc}>
        <li>
          <input
            type="checkbox"
            id="terms1"
            checked={registerCheck.terms1}
            onChange={handleCheckboxChange}
          />
          <label htmlFor="terms1">이용약관 동의 </label>
          <img
            className={styles.agreement_right}
            src="/assets/Term.svg"
            alt=""
            onClick={handleOpenAgreement}
          />
        </li>
        <li>
          <input
            type="checkbox"
            id="terms2"
            checked={registerCheck.terms2}
            onChange={handleCheckboxChange}
          />
          <label htmlFor="terms2">개인정보 수집 이용 동의 </label>
          <img
            className={styles.agreement_right}
            src="/assets/Term.svg"
            alt=""
            onClick={handleOpenAgreement}
          />
        </li>
      </ul>
    </div>
    <button
      className={`${styles["agree-button"]} ${registerCheck.terms1 && registerCheck.terms2 ? '' : styles.disabled}`}
      onClick={handleSubmitClick}
      disabled={!registerCheck.terms1 || !registerCheck.terms2}
    >
      모두 동의하고 가입하기
    </button>
  </div>
</Modal>
  • 모달 기본 설정: isOpen, onRequestClose, contentLabel 등을 설정하여 모달의 접근성과 동작을 보장합니다.
  • CSS Modules 적용: 클래스 이름을 styles 객체를 통해 적용합니다. (예: styles.Modal, styles["modal-contents"] 등)
  • 약관 항목 리스트: 체크박스와 라벨, 약관 상세보기 아이콘(이미지)을 포함합니다.
    • 아이콘 클릭 시 개인정보 안내 모달을 열도록 연결되어 있습니다.
  • 제출 버튼: 모든 필수 체크박스가 체크된 경우에만 활성화되고, 클릭 시 handleSubmitClick 함수가 실행됩니다.

5-2. 두 번째 모달 (개인정보 수집 안내 모달)

<Modal
  isOpen={isAgreementOpen}
  onRequestClose={handleCloseAgreement}
  contentLabel="Personal Information Collection"
  className={styles.Modal_TERM}
  overlayClassName={styles.Overlay_TERM}
>
  <div className={styles.agreement_box_TERM}>
    <p style={{ textAlign: 'left' }}>
      개인정보 수집 안내
      <br />
      <br /> 1. 개인정보 수집 목적
      <br />
      - 가톨릭대학교 중앙동아리 COMA는 다음 목적을 위해 개인정보를 수집합니다:
      <br />
      &nbsp; - 가톨릭대학교 총학생회 주관 아우름제 COMA 노점 이벤트인 COMAtching의 참여
      <br />
      <br />
      2. 수집하는 개인정보 항목 * 수집하는 개인정보 항목은 다음과 같습니다:{' '}
      <br />
      &nbsp;* 인적사항 <br />
      &nbsp; &nbsp;* 성명, 학번, 연락처 <br />
      <br />
      3. 개인정보 제 3자 제공 <br />
      &nbsp;* 수집한 개인정보는 다음 3자에게 정보가 제공됩니다: <br />
      &nbsp; &nbsp;* COMAtching 참여자 <br />
      4. 개인정보 보유 및 이용기간 <br />
      <br />
      &nbsp;2024년 5월 24일 23시 59분까지
      <br />
      <br /> * 개인정보는 수집 및 이용목적이 달성되면 지체 없이 파기됩니다. 다만, 관련 법규에 따라 보존할 필요가 있는 경우에는 해당 기간 동안
      안전하게 보관됩니다. <br />
      <br /> 5. 개인정보 수집 거부권 * 개인정보의 수집은 자발적으로 제공하실 수 있으며, 수집에 동의하지 않을 권리가 있습니다. 다만, 일부 정보를
      제공하지 않을 경우 가톨릭대 중앙동아리 COMA의 일부 서비스를 이용할 수 없을 수 있습니다. <br />
      <br /> 6. 개인정보 관련 문의 및 민원처리 <br />* 개인정보 수집과 관련한 문의사항이나 민원은 다음으로 문의해 주시기 바랍니다: <br />
      &nbsp;* 최고 정보 관리 책임자 : 가톨릭대학교 중앙동아리 COMA
      <br /> &nbsp;* 개인정보보호책임자 : 가톨릭대학교 정보통신전자공학부 19학번 박승원 <br />
      &nbsp;* 개인정보 수집 및 이용 주체 : 가톨릭대학교 중앙 IT동아리 COMA{' '}
      <br />
      <br />
      7. 개인정보 수집 및 이용 동의 * 본인은 개인정보 수집 및 이용에 대해 동의합니다.
    </p>
    <div className={styles.cancel_button_TERM} onClick={handleCloseAgreement}>
      닫기
    </div>
  </div>
</Modal>
  • 두 번째 모달: 개인정보 수집 및 이용에 관한 상세 안내를 보여줍니다.
  • 닫기 버튼: 클릭하면 모달을 닫아 isAgreementOpen 상태를 false로 변경합니다.

 

728x90