미새문지

24.08.16 day47 필터 구현 본문

개발 TIL

24.08.16 day47 필터 구현

문미새 2024. 8. 16. 23:21
728x90

자바스크립트는 객체나 배열에 대한 값을 import로 가져올 수 있다.

export const options = [
  "여드름",
  "아토피",
  "민감성",
  "저항성",
  "10대",
  "20대",
  "30대",
  "40대+",
  "모닝",
  "나이트",
  "남성",
  "여성",
];

이러한 배열을 외부에서 가져올 수 있게 export하여 사용할 코드로 가져온다.

import styled from "styled-components";
import React, { useState } from "react";
import { options } from "./Data";

const OtherFilter = () => {
  const [checkedItems, setCheckedItems] = useState([]);

  const handleCheckboxChange = (e) => {
    const value = e.target.value;
    if (checkedItems.includes(value)) {
      setCheckedItems(checkedItems.filter((item) => item !== value));
    } else {
      setCheckedItems([...checkedItems, value]);
    }
  };

  return (
    <>
      <FilterWrapper>
        {options.map((option, index) => (
          <Label key={index} isChecked={checkedItems.includes(option)}>
            <input
              type="checkbox"
              value={option}
              checked={checkedItems.includes(option)}
              onChange={handleCheckboxChange}
            />
            {option}
          </Label>
        ))}
      </FilterWrapper>
    </>
  );
};
export default OtherFilter;

const FilterWrapper = styled.div`
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  row-gap: 10px;
  padding: 10px;
`;

const Label = styled.label`
  width: 60px;
  padding: 2px 0;
  cursor: pointer;
  margin: 0 auto;
  font-size: 12px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  background-color: ${(props) => (props.isChecked ? "#FFA4E4" : "white")};
  border: 1px solid #c9c9c9;
  border-radius: 15px;

  &:hover {
    background-color: #ffa4e4;
  }

  input[type="checkbox"] {
    display: none;
  }
`;

그러면 가져온 해당 배열을 컴포넌트안에서 순회하며 각 배열의 인덱스 값마다 div를 만들어준다.

이 방식은 게시판의 게시글들을 가져올 때와 동일하다.

 

map으로 해당 배열의 값이 담긴 div들이 생성되고 중복체크를 위해 체크박스 형태로 구현을 해놨다.

체크를 위해 박스를 클릭할 시 useState로 배열에 담아주는데, 해당 체크값이 배열에 포함되어 있으면 체크 해제로 판단해 배열에서 삭제하고 포함되지 않았으면 추가해주는 방식이다.

 

import React, { useState } from "react";
import styled from "styled-components";

const PriceFilter = () => {
  const [minPrice, setMinPrice] = useState("");
  const [maxPrice, setMaxPrice] = useState("");
  const [minCount, setMinCount] = useState("");
  const [maxCount, setMaxCount] = useState("");

  // const products = [
  //   { id: 1, name: "Product A", price: 100 },
  //   { id: 2, name: "Product B", price: 200 },
  //   { id: 3, name: "Product C", price: 300 },
  //   { id: 4, name: "Product D", price: 400 },
  //   { id: 5, name: "Product E", price: 500 },
  // ];

  // const filteredProducts = products
  //   .filter((product) => {
  //     const price = product.price;
  //     const isWithinPriceRange =
  //       (!minPrice || price >= Number(minPrice)) &&
  //       (!maxPrice || price <= Number(maxPrice));
  //     return isWithinPriceRange;
  //   })
  //   .filter((product, index, array) => {
  //     const isWithinCountRange =
  //       (!minCount || index + 1 >= Number(minCount)) &&
  //       (!maxCount || index + 1 <= Number(maxCount));
  //     return isWithinCountRange;
  //   });

  return (
    <>
      <AsideFilterWrapper>
        <FilterTitle>제품 개수</FilterTitle>
        <FilterInput
          type="text"
          value={minCount}
          onChange={(e) => setMinCount(e.target.value)}
        />
        ~
        <FilterInput
          type="text"
          value={maxCount}
          onChange={(e) => setMaxCount(e.target.value)}
        />
      </AsideFilterWrapper>

      <AsideFilterWrapper>
        <FilterTitle>가격대</FilterTitle>
        <FilterInput
          type="text"
          value={minPrice}
          onChange={(e) => setMinPrice(e.target.value)}
        />
        ~
        <FilterInput
          type="text"
          value={maxPrice}
          onChange={(e) => setMaxPrice(e.target.value)}
        />
      </AsideFilterWrapper>

      {/* <div>
        <h3>제품 목록</h3>
        {filteredProducts.length > 0 ? (
          <ul>
            {filteredProducts.map((product) => (
              <li key={product.id}>
                {product.name} - {product.price}원
              </li>
            ))}
          </ul>
        ) : (
          <p>해당 조건에 맞는 제품이 없습니다.</p>
        )}
      </div> */}
    </>
  );
};
export default PriceFilter;

const AsideFilterWrapper = styled.div`
  display: flex;
  margin-left: 8%;
  margin-bottom: 10px;
`;

const FilterTitle = styled.div`
  width: 60px;
  font-size: 12px;
  text-align: right;
  line-height: 1.5;
  margin-right: 5%;
`;

const FilterInput = styled.input`
  width: 65px;
  border: 1px solid #c9c9c9;
  border-radius: 15px;
  margin: 0 5px;
  font-size: 12px;
`;

선택 필터가 아닌 수치적인 필터는 최소값과 최대값을 체크하는 방식이며 수치가 입력되면 onChange로 인해 변화된 값을 바로 감지해서 최소값 이상 최대값 이하의 값들을 보여준다.

그러나 전체 필터에서 적용을 시켜야 하기 때문에 해당 값을 상위 컴포넌트로 넘겨서 부모 컴포넌트에서 필터를 해야 하는데 이 부분은 이 후에 데이터를 받아와서 해야할듯

 

728x90

'개발 TIL' 카테고리의 다른 글

24.08.20 day49 로그인 UI  (0) 2024.08.20
24.08.19 day48 HTML 작성 규칙  (0) 2024.08.19
24.08.14 day46 CSS 적용 방식  (0) 2024.08.14
24.08.13 day45 타입스크립트 경로 에러, SPA  (0) 2024.08.13
24.08.12 day44 ESLint  (0) 2024.08.12