메인 페이지 뿐만 아니라 상품리스트에서도 텍스트만 바뀌고 동일한 Title로 작성됨
😎 Title Component로 작성해 섹션에 맞는 텍스트값만 바꿔줘야겠다!! 결심😎
🔎목표
주제목(Title
)과 부제목(SubTitle
) props로 전달 받기
<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>
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;
@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
의 카테고리명은 더보기 버튼 텍스트 이용<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>
flew-wrap: wrap 써서 한개의 li 태그안의 텍스트 한줄로 표현
4. 클릭한 카테고리만 메인 보라색으로 ⭐⭐⭐
useEffect
의 deps을 CurrentClick로 지정 -> 클릭한 카테고리가 바뀔 때마다 함수 실행되도록 함querySelector()
로 DOM에 접근 `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);
};