[React] 체크박스 및 카테고리 선택, 해제 기능 구현하기

Cottonmycotton·2022년 1월 30일
12

React

목록 보기
9/14
post-custom-banner

useState를 이용하여 체크박스 및 카테고리 선택 기능 구현하기!

1. 구현 기능 목록

1) 체크박스

  • 체크박스 구현하여 카테고리 리스트 만들기
  • 체크박스 선택시 리스트에 해당 카테고리 추가(중복 선택 가능)
  • 체크박스 지정 해제 시 카테고리 리스트에서 해당 카테고리 삭제

2) 카테고리 리스트

  • 카테고리 지정이 아무것도 안되어 있을 경우 리스트 칸에 "카테고리를 지정해주세요." 문구가 출력되어야 함
  • 선택된 카테고리 x 버튼을 클릭시 카테고리 지정 해제하기

2. 구현 과정

  • input type="checkbox" 로 지정
  • 체크박스 리스팅을 위해 상수데이터 만들기
    (카테고리 목록은 임의로 작성하였습니다.)
    const CATEGORY_LIST = [
      { id: 0, data: '서울' },
      { id: 1, data: '인천' },
      { id: 2, data: '경기' },
      { id: 3, data: '경북' },
      { id: 4, data: '경남' },
      { id: 5, data: '전북' },
      { id: 6, data: '전남' },
      { id: 7, data: '제주' },
    ];
    • map함수를 이용하여 렌더링 해준다
    • 상수데이터는 렌더될때마다 불러질 필요없이 한번만 불러와도 되니 함수 바깥으로 빼주기!
  • 리스트 갯수가 화면 길이를 초과할 경우 스크롤 기능 생성을 위해 스타일에 overflow: scroll 을 추가해주기
  • const [checkedList, setCheckedList] = useState([]);
    • 데이터를 저장할 빈배열
  • onCheckedElement 함수
    • onChange이벤트를 통해 체크박스 이벤트 감지하여, 체크시 데이터를 저장하고 체크해제시 filter함수를 사용해 데이터를 삭제한다
  • onRemove 함수
    • 리스팅 된 카테고리를 x 버튼을 누를 시 위와 마찬가지로 filter함수를 사용해 배열에서 데이터를 삭제한다
  • 리스팅 container에서 선택된 카테고리가 없을시 카테고리를 선택하라는 문구가 출력되어야 하는데, checkedList의 길이를 이용하여 조건부 렌더링에 적용시켰다. 빈배열일 경우 길이가 0이기 때문!

3. 코드(넘버링된 부분은 코드 아래에 설명 첨부)

import React, { useState } from 'react';
import * as S from '../ProdBasicInfo/ProdBasicInfo.Style';
// 카테고리 목록
const CATEGORY_LIST = [
  { id: 0, data: '서울' },
  { id: 1, data: '인천' },
  { id: 2, data: '경기' },
  { id: 3, data: '경북' },
  { id: 4, data: '경남' },
  { id: 5, data: '전북' },
  { id: 6, data: '전남' },
  { id: 7, data: '제주' },
];

function ProdBasicInfo() {
  // 데이터를 넣을 빈배열
  const [checkedList, setCheckedList] = useState([]);
  // 1️⃣ onChange함수를 사용하여 이벤트 감지, 필요한 값 받아오기
  const onCheckedElement = (checked, item) => {
    if (checked) {
      setCheckedList([...checkedList, item]);
    } else if (!checked) {
      setCheckedList(checkedList.filter(el => el !== item));
    }
  };
  // 2️⃣ x를 누르면 리스팅 목록에서 카테고리가 삭제되며 체크도 해제 된다
  const onRemove = item => {
    setCheckedList(checkedList.filter(el => el !== item));
  };
  
  return (
      <S.CategoryContainer>
        <S.Category>카테고리 *</S.Category>
        <S.SelectContainer>
    // map 함수를 이용해 체크박스 container에 체크박스 목록 생성하기 
          <S.CheckBox>
            {CATEGORY_LIST.map(item => {
              return (
                <S.Label key={item.id}>
                  <S.Check
                    type="checkbox"
                // 이때 value값으로 data를 지정해준다.
                    value={item.data}
               // onChange이벤트가 발생하면 check여부와 value(data)값을 전달하여 배열에 data를 넣어준다.
                    onChange={e => {
                      onCheckedElement(e.target.checked, e.target.value);
                    }}
               // 3️⃣ 체크표시 & 해제를 시키는 로직. 배열에 data가 있으면 true, 없으면 false
                    checked={checkedList.includes(item.data) ? true : false}
                  />
                  <S.Type>{item.data}</S.Type>
                </S.Label>
              );
            })}
          </S.CheckBox>
          <S.SelectedBox>
            // 여기서부턴 리스팅 container!
            // checkedList가 빈배열일 경우, 즉 아무 데이터도 없을땐 길이가0이므로 조건부 렌더링을 사용하여 "카테고리를 지정해주세요" 문구가 출력되게 한다.
            {checkedList.length === 0 && (
              <S.AlertMessage>{'카테고리를 지정해 주세요.'}</S.AlertMessage>
            )}
           // checkedList에 데이터가 들어가있을 경우 위와 마찬지로 map함수를 사용하여 데이터가 리스팅되도록 한다.
            {checkedList.map(item => {
              return (
                <S.SelectedCategory key={item}>
                  <S.Selected>{item}</S.Selected>
            // 카테고리를 삭제하면 배열에서 데이터가 삭제돠게 만드는 이벤트
                  <S.CancelChecked onClick={() => onRemove(item)}>
                    X
                  </S.CancelChecked>
                </S.SelectedCategory>
              );
            })}
          </S.SelectedBox>
        </S.SelectContainer>
      </S.CategoryContainer>
 );
};

  1. 함수 onCheckedElement는 체크박스에서 onChange이벤트가 발생했을 때 check여부와 이벤트가 발생한 data를 인자값으로 받아온다. 이때 checked가 true일땐 checkedList에 data를 넣어주어 리스팅container에 출력되도록 한다. chekced가 false일땐 filter함수를 이용하여 체크가 해지된 아이템을 배열에서 제거한다.

  2. 1번과 마찬가지로 리스팅된 카테고리에서 x를 누를 경우 클릭이벤트가 발생한 데이터를 배열에서 제거시킨다.

  3. checkedList에 데이터가 없을 경우 checked는 false가 되면서 체크가 해지되고 값이 있을경우 true가 되면서 체크가 된다. 즉 checkedList의 상태에 따라 체크상태가 바뀜.

profile
투명인간
post-custom-banner

0개의 댓글