본문 바로가기

Libraries/React

[React] 체크박스 (약관동의 만들기)

728x90

 

 

약관동의를 위한 체크박스를 만들어보자!

 

 

 

 

 만들 예제의 완성본 

 

1. 하위 체크 박스를 하나씩 선택해서 전체 체크 됐을때 전체동의 체크박스에 체크된다.
2. 체크박스가 전체 체크 된 상태에서 체크 박스가 한개 이상 해제되면 전체동의 체크박스가 해제된다. 
3. 전체동의 시에 체크박스 모두가 선택되고, 다시 누르면 모두가 해제된다.

 

 

 

 

 


 

 

 

 

 

 state를 생성한다. 

const [allAgreed, setAllAgreed] = useState(false);
const [agreements, setAgreements] = useState({
 termsAgreed: false,
 personalInfoAgreedEssential: false,
 personalInfoAgreedOptional: false,
 ageAgreed: false,

 

- allAgreed: 모든 확인란이 선택되었는지 여부를 추적한다.

- agreements: 개별 약관에 대해 상태를 초기화한다. 각 체크박스는 key-value로 표시된다.

 

 

 

 

 이벤트 핸들러 함수를 만든다. 

 

const handleAgreementChange = (event)=> {
    const { name, checked } = event.target;
   
    setAgreements((prevAgreements)=> ({ ...prevAgreements, [name]: checked }));
    const allChecked = Object.values({ ...agreements, [name]: checked }).every(
      (value)=> value === true
    );
    setAllAgreed(allChecked);
  };

 

- 전체동의 체크박스와 개별적으로 체크박스를 클릭했을 때 변경되는 이벤트를 처리한다.

- agreements 확인란 name과 checked 속성을 기반으로 상태를 업데이트한다.

 

 

 

 

 마크업 

 

<input
  type="checkbox"
  id="agree-check-all"
  name="agree-check-all"
  checked={allAgreed}
  onChange={handleAllAgreementChange}
  className={styles["agree-check-input"]}
/>
<label htmlFor="agree-check-all">전체 동의합니다.</label>

 

- 체크박스의 id는 label요소와 연결하기 위해 사용한다.

- label요소에는 htmlFor 속성을 사용해서 연결할 checkbox의 id를 지정해야한다.

- label의 htmlFor에 checkbox id 값과 동일하게 입력하면 label을 클릭해도 체크박스를 선택할 수 있다.


- checkbox의 name을 지정하여 폼을 서버로 전송 했을 때 체크된 상태의 checkbox 값을 서버로 전달하거나 클라이언트 측에서 폼 처리를 위해 사용한다.

 

 

 

 

 전체코드 

 

import { useState } from "react";
import styles from "./CheckBox.module.css";

export default function CheckBox() {
  const [allAgreed, setAllAgreed] = useState(false);
  const [agreements, setAgreements] = useState({
    termsAgreed: false,
    personalInfoAgreedEssential: false,
    personalInfoAgreedOptional: false,
    ageAgreed: false,
  });

  const handleAgreementChange = (event)=> {
    const { name, checked } = event.target;
   
    setAgreements((prevAgreements)=> ({ ...prevAgreements, [name]: checked }));
    const allChecked = Object.values({ ...agreements, [name]: checked }).every(
      (value)=> value === true
    );
    setAllAgreed(allChecked);
  };

  const handleAllAgreementChange = (event)=> {
    const { checked } = event.target;
    setAgreements((prevAgreements)=>
      Object.keys(prevAgreements).reduce(
        (newAgreements, agreementKey)=> ({
          ...newAgreements,
          [agreementKey]: checked,
        }),
        {}
      )
  );
    setAllAgreed(checked);
  };
  
  
  return (
    <div className={styles["signup-terms-of-service-container"]}>
          <label className={styles["signup-terms-of-service"]} >이용약관동의</label>
          <ul className={styles["signup-terms-of-service-checkbox-container"]}>
            <li>
              <input
                type="checkbox"
                id="agree-check-all"
                name="agree-check-all"
                checked={allAgreed}
                onChange={handleAllAgreementChange}
                className={styles["agree-check-input"]}
              />
              <label htmlFor="agree-check-all">전체 동의합니다.</label>
              <p  className={styles["agree-check-all-info"]}>선택 항목에 동의하지 않은 경우도 회원가입 및 일반적인 서비스를 이용할 수 있습니다.</p>
            </li>
            
            <hr className={styles["agree-check-hr"]} />
            <li>
              <input
                type="checkbox"
                id="agree-check-used"
                name="termsAgreed"
                required
                checked={agreements.termsAgreed}
                onChange={handleAgreementChange}
                className={styles["agree-check-input"]}
              />
              <label htmlFor="agree-check-used">서비스 이용약관 동의 (필수)</label>
             
            </li>
            <li>
              <input
                type="checkbox"
                id="agree-check-info-essential"
                name="personalInfoAgreedEssential"
                required
                checked={agreements.personalInfoAgreedEssential}
                onChange={handleAgreementChange}
                className={styles["agree-check-input"]}
              />
              <label htmlFor="agree-check-info-essential">
              개인정보 수집 및 이용 동의 (필수)
              </label>
              
            </li>
            <li>
              <input
                type="checkbox"
                id="agree-check-info-optional"
                name="personalInfoAgreedOptional"
                required
                checked={agreements.personalInfoAgreedOptional}
                onChange={handleAgreementChange}
                className={styles["agree-check-input"]}
              />
              <label htmlFor="agree-check-info-optional">
              개인정보 수집 및 이용 동의 (선택)
              </label>
              
            </li>
            <li>
              <input
                type="checkbox"
                id="agree-check-age"
                name="ageAgreed"
                required
                checked={agreements.ageAgreed}
                onChange={handleAgreementChange}
                className={styles["agree-check-input"]}
              />
              <label htmlFor="agree-check-age">만 14세 이상입니다. (필수)</label>      
            </li>
          </ul>
      </div>
  );
}

 

 

728x90