✨ [카테고리] '전체' 카테고리와 나머지 카테고리들 구분한 필터 구현

Sheryl Yun·2022년 11월 21일
0

Effitizer 프로젝트 메인 화면의 카테고리 필터 구현에 성공했다. 경우의 수가 많지 않아서 금방 만들 수 있을 줄 알았는데 코드 에디터에서 바로 하려니 생각보다 잘 안 돼서 종이에 써 가면서 했다. 쓰다보니 분기가 3 depth까지 내려간다는 걸 알게 되었다.

구현한 영상

  1. 처음 렌더링 시작할 때 전체 카테고리가 선택되어 있다. (*백엔드에서 받은 데이터가 '음악'으로 시작하여 맨 앞의 '음악' 카테고리를 '전체' 카테고리라고 생각하고 작업)
  2. 전체 외에 다른 카테고리를 선택하면 (더 이상 전체가 아니게 되므로), 전체 카테고리는 삭제하고 그 외에 클릭한 카테고리들만 선택한다.
  3. 전체 외에 다른 카테고리들은 복수 선택이 가능하다.
  4. 모든 카테고리들은 토글(toggle)된다. (= 버튼에 색이 들어왔다 나갔다 함)
  5. 다른 카테고리들을 선택하다가 전체 카테고리를 누르면, 선택되었던 카테고리들은 모두 사라지고 전체 카테고리만 선택된다.

분기 작성 내역

변수는 총 2가지이다.
1. 클릭한 카테고리의 인덱스 -> 0인지 아닌지
2. 클릭한 카테고리의 인덱스들이 담긴 배열 -> 0을 포함하는지 아닌지

분기가 발생하는 로직은 총 4가지이다.

  • 클릭한 카테고리의 인덱스가 0인지 아닌지 (2가지)
  • 클릭한 카테고리의 인덱스들이 담긴 배열이 0을 포함하는지 아닌지 (2가지)

여기서 0은 '전체' 카테고리를 뜻한다.

초기상태와 변수

  • 아무 선택을 하지 않았을 때 (초기 상태)
    • 맨 앞의 '전체' 카테고리만 선택되어 있다
  • 변경되는 요소(변수) 2가지
    • 클릭한 인덱스
    • 클릭한 인덱스들만 모은 배열

(촬영: 'CamScanner' 앱 사용)

분기 로직

'클릭한 인덱스'는 클릭한 카테고리의 인덱스이고,
'클릭한 배열'은 클릭한 카테고리의 인덱스들이 담긴 배열이다.

제일 먼저 '클릭한 배열'에 0이 있는지 여부로 크게 나뉜다.
그리고 2번의 두 번째 경우( '2)' )에서 두 가지 분기로 나뉜다.

코드

특정 카테고리 클릭 시 handleCategoryClick을 실행한다. (styles는 SCSS 코드)

          <div className={styles.categoryList}>
            {categories?.map(({ id, name }) => (
              <div
                key={id}
                className={classNames(
                  styles.categoryButton,
                  clickedCategories.map(
                    (clickedIndex) =>
                      clickedIndex === id - 1 && styles.clickedCategory
                  )
                )}
                onClick={() => handleCategoryClick(id - 1)}
              >
                {name} // 카테고리 이름 (음악, 경제, .. )
              </div>
            ))}
          </div>

⚜ handleCategoryClick 함수 ⚜

 const handleCategoryClick = (clickedIndex: number) => {
    if (clickedCategories.includes(0)) {
      if (clickedIndex === 0) {
        return;
      } else {
        setClickedCategories([
          ...clickedCategories.filter((clicked) => clicked !== 0),
          clickedIndex,
        ]);
      }
    } else {
      if (clickedIndex === 0) {
        setClickedCategories([0]);
      } else {
        if (clickedCategories.includes(clickedIndex)) {
          setClickedCategories([
            ...clickedCategories.filter((clicked) => clicked !== clickedIndex),
          ]);
        } else {
          setClickedCategories([...clickedCategories, clickedIndex]);
        }
      }
    }
  };

종이에 로직을 적어보니 변경되는 요소와 변경할 로직이 명확해져서 금방 구현할 수 있었다. 에디터에서만 코딩할 때는 계속 제자리만 돌고 진도가 안 나가는 느낌이었는데 역시 손노동이 짱이다.

profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글