0216 ~ 0219 : 카테고리 선택 & 상품 목록

히치키치·2022년 2월 16일
0

Book_Curly

목록 보기
5/8

✔ 실제 마켓컬리 카테고리 분석

  1. "MD의 추천"의 title 있으며 다른 Section의 title과 동일한 형태
    -> Component로 작성해 재사용
  2. 카테고리명(value)
    -> 가로/중앙으로 나열
    -> 마우스 hover 연하게 색상 변화
    -> 클릭시 해당 카테고리가 메인 보라색으로 변하고 그에 맞는 상품 나옴
  3. 카테고리 선택 시 해당 상품 Carousel로 나옴
    -> 이전에 작성한 Carousel 컴포넌트 이용
  4. {카테고리명} 더보기 버튼 있음
    -> 사용자가 카레고리명 클릭 시 해당 value 잘 담아둬야 함

✔ Title 컴포넌트



메인 페이지 뿐만 아니라 상품리스트에서도 텍스트만 바뀌고 동일한 Title로 작성됨
😎 Title Component로 작성해 섹션에 맞는 텍스트값만 바꿔줘야겠다!! 결심😎

🔎목표
주제목(Title)과 부제목(SubTitle) props로 전달 받기

  1. 페이지와 섹션에 맞는 Title과 SubTitle의 텍스트 값 전달
    <div id="main">
      <section className="BestSeller">
        <Title
          Title={"국내 베스트셀러"}
          SubTitle={"북컬리에서 가장 먼저 만나는 인기 도서"}
        />
        <Carousel
          URL={
            "http://book.interpark.com/api/bestSeller.api?key=89A91C143CDE9705B057F05F9A1F5B538CD290A7AD80599201DCE4401BEEFE8A&output=json&categoryId=100"
          }
        />
      </section>
      <section className="BestCurly">
        <Title Title={"북컬리 추천"} />
        <Category CategoryArray={CategoryArray} />
      </section>
  </div>
  1. Title 컴포넌트 작성
import React from "react";
import "./Title.scss";

function Title({ Title, SubTitle }) {
  console.log(Title, SubTitle);
  return (
    <div className="Title">
      <span> {Title}</span>
      <p>{SubTitle}</p>
    </div>
  );
}

export default Title;
  1. Title 컴포넌트 스타일링 적용
@import "../../../Styles/common.scss";
@import "../../../Styles/reset.scss";

.Title {
  @include flexCenter();
  @include CenterContainer();
  span {
    color: $txt-dark-gray;
    font-size: $font-large;
    font-weight: 600;
    padding: 8px;
  }
  p {
    color: $txt-light-gray-1;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.45;
    margin-top: 2px;
  }
  margin-bottom: 25px;
}

✔ 카테고리




사용자에게 카테고리명 보여줘야 함
해당 카테고리 명으로 API 요청 위해 카테고리 key 값 필요
중간 중간 카테고리명과 key 값의 변동이 있음
😎카테고리 명과 key 함께 & 카테고리 변경이 함수에는 영향 X😎

🔎목표
1. 카테고리명과 key 함께 변수로 저장
2. map을 이용해 카테고리명(value) 생성
-> 변수 변경 따라 따로 HTMl, CSS 만질 필요 X
3. 현재 클릭 카테고리만 active 클래스명 부여해 이에 CSS 적용
4. 현재 클릭 카테고리 키(key)로 API 요청 / Carousel 컴포넌트 사용
5. 현재 클릭 카테고리 명(value)로 더보기 버튼 안에 텍스트 동적으로 변동
6. 더보기 버튼 클릭시 해당 카테고리 키(key)로 API 요청해 해당 카테고리 전체 책 리스트로 이동

1. 카테고리명과 key 변수

  const CategoryArray = [
    { key: 101, value: "소설" },
    { key: 102, value: "시/에세이" },
    { key: 119, value: "인문" },
    { key: 110, value: "아동" },
    { key: 112, value: "청소년" },
    { key: 117, value: "경제경영" },
    { key: 118, value: "자기계발" },
    { key: 122, value: "컴퓨터/인터넷" },
    { key: 115, value: "국어/외국어" },
    { key: 200, value: "외국도서" },
    { key: 428, value: "블루레이" },
    { key: 400, value: "CD/DVD" },
  ];

2. map 이용해 카테고리명 보이기

  • ul의 list 안에 map 이용해 li로 카테고리명 생성
  • li 내 속성으로 value 속성에는 카테고리 키, name 속성에는 카테고리명 부여 해 클릭 이벤트 타켓으로 카테고리 키와 카테고리 명 가져오도록 함
      <ul className="list">
        {CategoryArray.map((Category) => (
          <li
            onClick={(e) => {
              setActive(e);
            }}
            value={Category.key}
            name={Category.value}
          >
            {Category.value}
          </li>
        ))}
      </ul>

3. 클릭 이벤트 통해 받은 카테고리 명/키 사용

  • 클릭 이벤트 발생 전 최초의 상태 정의
  const [CurrentClick, setCurrentClick] = useState(CategoryArray[0].key);
  const [PrevClick, setPrevClick] = useState(null);
  const [Btntext, setBtntext] = useState(CategoryArray[0].value);
  • 클릭 이벤트 발생시 이벤트 발생 li 태그 내 속성 이용해 setstate 해줌
const setActive = (e) => {
    setCurrentClick(e.target.getAttribute("value"));
    setBtntext(e.target.getAttribute("name"));
  };
  • 클릭한 li의 카테고리명은 더보기 버튼 텍스트 이용
  • 카테고리 키로 API 요청 이용
<Carousel URL={`http://book.interpark.com/api/bestSeller.api?key=89A91C143CDE9705B057F05F9A1F5B538CD290A7AD80599201DCE4401BEEFE8A&output=json&categoryId=${CurrentClick}`}
      />
      <button className="category_btn">
        <Link
          to={ "/list" }
        >
          {Btntext} 전체보기
        </Link>
      </button>

display : flex, flex-direction:row만 CSS 적용하면 다음과 같이 됨

flew-wrap: wrap 써서 한개의 li 태그안의 텍스트 한줄로 표현

4. 클릭한 카테고리만 메인 보라색으로 ⭐⭐⭐

  • useEffectdeps을 CurrentClick로 지정 -> 클릭한 카테고리가 바뀔 때마다 함수 실행되도록 함
  • querySelector()로 DOM에 접근
  • 복잡한 Selector : div 태그 Category 클래스 내 ul 태그 list 클래스 내 li 태그 속성 중 value 값이 CurrentClick과 동일한 것
 `div.Category ul.list li[value="${CurrentClick}"]`

setAttribute("속성", "값") 이용해 동적 클래스명 지정
1. 새로운 클릭한 카테고리가 CurrentClick으로 setState됨
2. 새로운 클릭한 카테고리인 li 태그 클래스명 active 부여
3. 이전 클릭 카테고리 존재하면 li 태그 클래스명 active 삭제
4. 이전 클릭 카테고리 값을 새로운 클릭 카테고리 값으로 설정
-> 사용자가 카테고리 값 선택하면 이를 CurrentClick setState됨

  useEffect(
    (e) => {
      if (CurrentClick !== null) {
        //console.log(CurrentClick);
        let current = document.querySelector(
          `div.Category ul.list li[value="${CurrentClick}"]`
        );
        // console.log("curr_click", current);
        current.setAttribute("class", "active");
      }

      if (PrevClick !== null) {
        console.log(PrevClick);
        let prev = document.querySelector(
          `div.Category ul.list li[value="${PrevClick}"]`
        );
        //console.log("prev_click", prev);
        prev.setAttribute("class", "");
      }
      setPrevClick(CurrentClick);
    },
    [CurrentClick]
  );

5. 더보기 버튼 클릭시 카테고리명에 맞는 title과 API 요청 ⭐⭐⭐

router params match는 url에 다 노출해야하며 전달해야하는 값이 많은 경우 URL주소가 길어진다는 단점 존재

Link to의 path와 state 이용해 여러값 라우팅 전달
1. pathname으로 라우팅 URL 지정
2. state로 전달한 값 작성
3. props.location.state로 전달 받음

     <button className="category_btn">
        <Link
          to={{
            pathname: "/list",
            state: {
              value: Btntext,
              key: CurrentClick,
            },
          }}
        >
          {Btntext} 전체보기
        </Link>
      </button>

Link to의 state로 전달받은 값은 props.location.state에 있음

const List = (props) => {
  const { key, value } = props.location.state;
  //console.log(key, value);
  return (
    <div className="List">
      <Title Title={value} />
      <Grid params={key} />
    </div>
  );
};

export default List;

sort 조건 요청이 불가능한 API
인터파크 API는 아주 오래전에 작성되어 ... 앞에서 sort조건을 요청변수로 주어서 GET을 할 수 없었닥....(오직 카테고리값만 지정해 요청가능...)

그리하여 프론트단에서 GET으로 받아아온 JSON데이터를 직접 다시 정렬하는 함수를 작성해서 이용하기로 하며 해결했다. 일단

여기서 정렬 기준이 될 수 있는 키값은 pubDate, reviewCount, discountRate, priceStandard 였다. 그리고 정렬이 오름차순인지 내림차순인지도 정해야해서 이렇게 실제 전체 목록에 사용할 정렬 기준을 따로 작성했다.

export const OrderStandard = [
  {
    key: "pubDate_desc",
    value: "신상품",
  },
  {
    key: "reviewCount_desc",
    value: "리뷰수",
  },

  {
    key: "discountRate_desc",
    value: "할인율",
  },
  {
    key: "priceStandard_asc",
    value: "낮은 가격",
  },

  {
    key: "priceStandard_desc",
    value: "높은 가격",
  },
];

사용자에게는 value값이 화면에 보여짐

이중에서 사용자가 특정정렬 기준을 원해 클릭하면 키(기준과 오름차순/내림차순이 합쳐진)가 전달되며 받아온 책JSON을 재정렬하는 Reorder 함수가 실행됨. Reorder 함수 내에서 기준과 나열 순서를 분리하고 기준에 따라 책을 전체적으로 정렬하고 오름차순/내림차순에 따라 앞뒤 순서만 바꾼다.

  const Reorder = (standard) => {
    //console.log(standard);
    setvalue(standard);
    var type;
    if (standard.indexOf("_asc") !== -1) {
      type = "asc";
      standard = standard.replace(/_asc/g, "");
    } else if (standard.indexOf("_desc") !== -1) {
      type = "desc";
      standard = standard.replace(/_desc/g, "");
    }

    console.log(type, standard);

    if (GetData) {
      setGetData(
        GetData.sort(function (a, b) {
          var x = a[standard];
          var y = b[standard];
          if (type === "desc") {
            return x > y ? -1 : x < y ? 1 : 0;
          } else if (type === "asc") {
            return x < y ? -1 : x > y ? 1 : 0;
          }
        })
      );
    }
    console.log(GetData);
  };

0개의 댓글