1차 프로젝트 Day 11🔥
(유동 라우터 url parameter 및 상품 컬러 별/가격 별 filter,sort 정리)
쇼핑몰 페이지에서 구현해야 하는 기능 중, 상품 리스트 페이지에서 상품을 클릭했을 때 그 해당 상품의 상세 페이지를 보여 주게끔 해야 하는데, 이때 사용되는 것이 유동 라우팅 이다.
유동 라우팅의 경우, Query parameters와 URL parameters
가 있는데 특별한 필터링이 필요할 경우에는 Query parameters 사용이 적합
하고 보통의 커머스에서 Query parameters를 사용하지만, ami 사이트는 URL parameters를 사용해서 우리도 URL parameters를 사용하였다. 완벽 정리된 준식님 블로그
즉 지정된 라우팅이 아니라 경로 뒤에 변수값을 줘서 그때 그때 🌻 마다 다른 주소의 브라우저가 render 된다는 의미!
백엔드와 url 구조를 align 한다.
- URL parameter를 구현 하려면 각 json 데이터의 고유 값으로 상품을 매칭 해야 하는데, ami 프로젝트의 경우 백엔드에서 작업중인 데이터에 고유한 id 값이 없어서, 고유한 id 값+ 색상 값
으로 필터할 수 있게끔 합의하였다.
Routes.js 파일에서 백엔드와 align된 url 주소 형식을 기입한다.
우리의 경우 /id
/color/colorId
의 형태로 만들기로 했기 때문에 아래와 같이 입력해 주었다.
아래의 :
뒤에 입력하는 부분이 우리가 사용할 부분을 의미한다.
<Route exact path="/shopping/man/:id/color/:colorId"
component={ProductDetailwData}/>
클릭
했을때, 해당 경로로 이동하는 logic 이므로, 상품 컴포넌트의 의 click 이벤트에서 인자를 두개 받는( 클릭하는 요소의 id, colorid 값) 함수를 지정해 준다. 코드를 쉽게 보기위해 전달해줄 props key 값 만 남겨두었다. <Product onClick={() => this.clickHandler(item.product_id, item.product_color_id)}
id={item.product_id}
colorId={item.product_color_id}
/>
clickHandler
함수 내에서 this.props.history.push
를 통해 url 경로를 추가해 준다. clickHandler = (id, colorId) => { this.props.history.push(`/shopping/man/${id}/color/${colorId}`);
};
this.props.match.params.id
의 형식이지만 destructuring을 통해 간결하게 표현 하였다. componentDidMount() {
const { id, colorId } = this.props.match.params;
fetch(`http://13.125.209.10:8000/product/${id}/color/${colorId}`)
.then((res) => res.json())
.then((res) =>
this.setState({
상품 리스트에서 상품 가격 순, 색상 순 으로 정렬하는 코드를 activeTab을 활용해서 구현하였다. 물론 리펙토링이 필요하지만 내일 구현
까지의 정도로만 우선 정리하고 돌아와서 다시 수정해야 겠다.
activeTab 의 state 값(숫자)
으로 component에서 render하고자 하는 내용을 sort 하려고 한다. 필터되서 보여주고자 하는 내용을 변수로 지정
하고, 변수를 컴포넌트 의 data props에 담는 형식
으로 매 번 새로운 렌더를 해주는 방식이다. this.state = {
data: [],
activeTab: "",
};
}
select 태그에는 선택된 옵션의 value를 넘겨주는 함수
를, option tag에는 각 tag의 value name을 지정해주어, 넘겨주는 activeTab과 매칭 될 수 있도록
한다. <select onChange={this.valueHandler}>
<option value="0">Sort by</option>
<option value="1">Lower prices</option>
<option value="2">Higher prices</option>
</select>
select된 값의 value 넘버가 active Tab으로 setState
한다. valueHandler = e => {
this.setState({ activeTab: e.target.value });
};
render() {
const { data, activeTab } = this.state;
const sortByLowerPrices = data.sort((a, b) => a.product_price - b.product_price);
const sortByHigerPrices = data.sort((a, b) => b.product_price - a.product_price);
component의 data props 값을 해당 변수로 변경
시킨다. const obj = {
0: <ProductList data={data} />,
1: <ProductList data={sortByLowerPrices} />,
2: <ProductList data={sortByHigerPrices} />
}
{data && obj[activeTab]}
리액트의 lifecycle 때문에 보통 데이터를 가져오는경우 항상 &&로 값이 있을 때 라는 조건을 다 달아 주었다. 나중에 리펙토링 할때는 아예 전체 데이터를 묶으면 적어도 계속해서 &&를 붙이는 코드는 안 만들어도 될 것 같다.
const blackColorOnly = data.filter((obj) => {
return obj.product_color === "BLACK";
});
const obj = {
0: <ProductList data={data} />,
1: <ProductList data={sortByLowerPrices} />,
2: <ProductList data={sortByHigerPrices} />,
3: <ProductList data={blackColorOnly} />,
4: <ProductList data={beigeColorOnly} />,
5: <ProductList data={offWhiteColorOnly} />,
6: <ProductList data={taupeColorOnly} />,
7: <ProductList data={clayColorOnly} />,
8: <ProductList data={greenColorOnly} />,
};
이렇게 코드를 작성하였을때 기능은 구현되었는데, 자동으로는 렌더가 안되는 현상을 경험했다. 사진 각 각에 마우스로 호버를 해줘야 전체가 바뀌어서 좌절중이었는데, 결국 알게된 사실은 REACT의 특성상 각각은 고유의 KEY 값을 가지고 있어야 하는데, 여기서는 데이터가 변경되면서 INDEX값이 고유해 지는것이 아니라 변경 되어서, 그 고유한 값이 필요했던 것. 그래서 임의로 KEY 값에 아래와 같이 적용 했더니 그 버그가 사라졌다 흐아~~~
<Product onClick={() => key={`${item.product_id}_${idx}`}}/>
내일은 프로젝트 발표 D-DAY다! 모두가 한 마음으로 달려왔고, 주말엔 더위와 싸워가며 (위워크 주말에 에어콘ㅠㅠ틀어주는 날이 올까..?) 저녁엔 모기와 싸워가며(10층인데 어디서 모기가 이렇게 올라오는걸까? 저녁에도 에어콘을 틀어주는 날이 올까?) 완성한 결과물을 확인하는 내일! 이때 까지는 기능 구현을 위해 각자 자신에게 채찍질만 하면서 달려온 것 같다. 몇 몇 팀원들이 끝으로 갈수록 많이 힘들어하는게 보여서 나도 같이 마음이 무거웠다. 나와의 싸움이기 때문에 해줄 수 있는게 없어서 할 수 있는 거라곤 ㅠㅠ 팀의 당 충전을 책임지는 정도?ㅠㅠ밖에 없어서 미안했고, 내가 고른 웹사이트가 애먹이는 느낌이라 괜시리 또 미안했다 ㅠㅠ 내일만은 아무쪼록 우리 모든 팀원들이 토닥토닥하고 쓰담쓰담하는 내일이 되었으면 좋겠다!🥇🥇🏆🏆