React와 Express로 체크박스 필터링

henry·2024년 11월 5일


1. 체크박스 선택 시 onChange 이벤트 발생

  • 체크박스를 선택하면 CheckBox 컴포넌트의 onChange 이벤트가 발생하여 handleToggle 함수가 실행
<input
   type='checkbox'
   onChange={() => handleToggle(continent._id)}
   checked={checkedContinents.indexOf(continent._id) !== -1}
   className='mr-1'
/>

onChange={() => handleToggle(continent._id)}

  • 체크박스를 클릭하면 handleToggle 함수가 호출
  • 현재 체크한 대륙의 ID인 continent._id를 인수로 전달

2. handleToggle 함수 실행

  • handleToggle 함수가 실행되면서 체크박스 상태 변경
const handleToggle = (continentId) => {
   const currentIndex = checkedContinents.indexOf(continentId);
   const newChecked = [...checkedContinents];

   if (currentIndex === -1) {
      newChecked.push(continentId);
   } else {
      newChecked.splice(currentIndex, 1);
   }
   onFilters(newChecked);
};

로직 분석

currentIndex = checkedContinents.indexOf(continentId);

  • 현재 클릭한 continentId가 checkedContinents 배열에 있는지 확인
  • 배열에 포함되지 않은 경우 -1을 반환
  • 포함된 경우 해당 위치의 인덱스를 반환

const newChecked = [...checkedContinents];

  • 현재 선택된 대륙들의 ID가 담긴 checkedContinents 배열을 복사하여 newChecked라는 새로운 배열을 생성

if (currentIndex === -1) newChecked.push(continentId);

  • 클릭한 continentId가 checkedContinents에 없으면, newChecked 배열에 추가(사용자가 새로운 대륙을 체크한 경우)

else { newChecked.splice(currentIndex, 1); }

  • 클릭한 continentId가 checkedContinents에 이미 포함되어 있는 경우
  • newChecked에서 해당 대륙을 제거 (사용자가 기존에 체크된 대륙을 해제한 경우)

onFilters(newChecked);

  • 최종적으로 업데이트된 newChecked 배열을 onFilters 함수에 전달하여 상위 컴포넌트(LandingPage)로 새로운 필터 상태를 전달

3. onFilters 호출 시 handleFilters 실행

onFilters 함수는 LandingPage 컴포넌트handleFilters 함수로 연결

<CheckBox
   continents={continents}
   checkedContinents={filters.continents}
   onFilters={(filters) => handleFilters(filters, 'continents')}
/>

onFilters={(filters) => handleFilters(filters, 'continents')}

  • onFilters에 전달된 newChecked 배열을 handleFilters 함수의 첫 번째 매개변수 filters로 전달
  • 두 번째 매개변수 category에는 'continents'라는 문자열을 전달

4. handleFilters 함수 실행

  • handleFilters 함수는 filters 상태를 업데이트
  • 새로운 조건으로 상품 목록을 조회
const handleFilters = (newfilteredData, category) => {
   const newFilters = { ...filters };
   newFilters[category] = newfilteredData;

   showFilteredResults(newFilters);
   setFilters(newFilters);
};

로직 설명

const newFilters = { ...filters };

  • 현재 필터 상태인 filters 객체를 복사하여 newFilters라는 새로운 객체를 생성

newFilters[category] = newfilteredData;

  • newfilteredData를 newFilters의 해당 카테고리에 할당
  • 여기서 category는 'continents'이고, newfilteredData는 새로운 필터 상태(newChecked 배열)
  • newFilters의 최종 구조는 { continents: [선택된 대륙 ID들], price: [] }

showFilteredResults(newFilters);

  • showFilteredResults 함수를 호출하여 새로운 필터 조건에 맞는 상품을 서버에 요청
  • 상품 목록을 다시 불러와 화면에 표시하는 함수

setFilters(newFilters);

  • filters 상태를 newFilters로 업데이트
  • 변경된 필터 조건이 LandingPage 컴포넌트에 반영

5. showFilteredResults 함수로 상품 목록 조회

  • showFilteredResults 함수는 서버에 새로운 필터 조건을 전달
  • 필터링된 상품 목록을 다시 불러오는 역할
const showFilteredResults = (filters) => {
   const body = {
      skip: 0,
      limit,
      filters,
   };
   fetchProducts(body);
   setSkip(0);
};

로직 설명

const body = { skip: 0, limit, filters };

  • skip 값을 0으로 설정하여 첫 번째 페이지부터 데이터를 조회
  • limit과 filters는 각각 상품 개수 제한필터 조건을 전달

fetchProducts(body);

  • fetchProducts 함수가 서버에 요청을 보내 필터 조건에 맞는 상품 목록 조회

setSkip(0);

  • 페이지네이션을 위해 사용되는 skip 값을 0으로 초기화
  • 첫 페이지부터 데이터를 가져오도록 설정합니다.

0개의 댓글