- 페이지네이션과 솔트
이 페이지 정렬부분의 원래코드는 백앤드에서 페이지네이션만 받아오고 프론트에서 sort기능을 해주었었다.
componentDidUpdate(prevProps, prevState) {
if (
prevState.offset !== this.state.offset ||
prevState.order_id !== this.state.order_id
) {
fetch(
`http://10.58.3.134:8000/products/women/outer?offset=${this.state.offset}&limit=${LIMIT}`
)
.then(res => res.json())
.then(data => {
this.setState({
goods: data.goods,
filterdFunction: data.goods,
nonfilterd: data.goods,
});
});
}
}
sortByPrice = e => {
const priceCompare = e.target.getAttribute('name');
const sortByPrice = [...this.state.goods].sort(function (a, b) {
return a[priceCompare] - b[priceCompare];
});
this.setState({ goods: sortByPrice });
};
sortByPriceDesc = () => {
const priceCompare = 'price';
const sortByPrice = [...this.state.goods].sort(function (a, b) {
return b[priceCompare] - a[priceCompare];
});
this.setState({ goods: sortByPrice });
};
sortByName = () => {
const nameCompare = 'name';
const sortByName = [...this.state.goods].sort(function (a, b) {
return a[nameCompare] < b[nameCompare]
? -1
: a[nameCompare] > b[nameCompare]
? 1
: 0;
});
this.setState({ goods: sortByName });
};
그런데 이렇게 되면, 리액트 라이프사이클에 의해서
1. componentDidUpdate가 먼저 실행,
2. 사용자가 onClick시, 정렬함수가 실행
되기 때문에 우리가 원하던 sort와는 조금 맞지 않았다.
만약에 상품이 60개가 있고, 페이지당 15개씩 보여준다고 치면,
전체 상품에 60개에 대해 낮은가격순/높은 가격순이 정렬되어 15개씩 끊어서 보여주어야하는데,
먼저 15개씩 끊어서 한페이지를 보여주고 그 15개 상품에 대해서만 정렬되는 거였기 때문이다.
아쉽지만 하루걸려 짜놓고 매우 뿌듯해하던 내 소듕한,,,sort기능을 싹 다 포기하고,,🥺 정렬기능도 백앤드에서 받아오는걸로 대체하였다.
[바뀐 코드]
componentDidUpdate(prevProps, prevState) {
if (
prevState.offset !== this.state.offset ||
prevState.order_id !== this.state.order_id
) {
fetch(
`http://10.58.3.134:8000/products/women/outer?offset=${this.state.offset}&limit=${LIMIT}&order_id=${this.state.order_id}`
)
.then(res => res.json())
.then(data => {
this.setState({
goods: data.goods,
filterdFunction: data.goods,
nonfilterd: data.goods,
});
});
}
}
sortByPrice = () => {
this.setState({ order_id: 1 });
};
sortByPriceDesc = () => {
this.setState({ order_id: 2 });
};
sortByName = () => {
this.setState({ order_id: 3 });
};
sortByNew = () => {
this.setState({ order_id: 0 });
};
백앤드에 신상품순/높은가격순/낮은가격순/이름순 등의 sort정보가 저장되어 있고, onClick시 setState를 통해 그에 맞는 value로 바꿔준뒤, componentDidUpdate로 다시 요청 url을 유동적으로 fetch 해온다.
이렇게 바꾸니까 코드도 간결해지고 우리가 원하던 방향으로 잘 작동하였다!!!!
10분만에 백엔드 로직 짜주신 기용님 감사합니다~
처음엔 내 피같은 기능들을 버리기 아까웠는데, 결과적으로 백앤드에서 받아온느 법도 익히고 프론트에서 기능 구현하는 법도 익힐 수 있어서 좋았다.😋👏🏽👏🏽👏🏽
💡 또 여기서 알아두어야 할 것 하나!
(componentDidUpdate를 할때는 꼭 조건을 걸어주어야 된다. 안그러면 무한 랜더링됌...)
내가 fetch에서 가져올 데이터를 고려해서 조건에 넣어준다!
componentDidUpdate(prevProps, prevState) {
if (
prevState.offset !== this.state.offset ||
prevState.order_id !== this.state.order_id
) {
fetch(
`http://10.58.3.134:8000/products/women/outer?offset=${this.state.offset}&limit=${LIMIT}&order_id=${this.state.order_id}`
)
.then(res => res.json())
.then(data => {
this.setState({
goods: data.goods,
filterdFunction: data.goods,
nonfilterd: data.goods,
});
});
}
}
- 조건부랜더링
html,css에서 flex를 사용하여 상품들의 간격을 맞추었다.
상품을 3개씩 보여주는데, 상품의 마지막이 1,3으로 끝나면 상관없는데 2개로 떨어질땐, 2개의 간격이 공평해지다보니까 상품이 멀찍이 떨어지는 상황이 발생했다.
이런상황,,,,
조건부 랜더링으로 전체 상품의 갯수 %3===2 일때 상품 1개의 데이터와 똑같은 width,height 를 가진 div를 하나 추가하면서 이를 해결 할 수 있었다.
(현업에선 왠지 이렇게 안할 것 같지만? 최대한 머리를 굴려서 내놓은 방법은 이거.. 물론 더 좋은 방법이 있을거 같다. 아시는 분 댓글 부탁드립니다 😂)
class GoodList extends Component {
render() {
const { goods } = this.props;
return (
<>
{goods.map(item => {
const { name, price, review_count, img_urls } = item;
return (
<Goods
key={name}
item={item}
name={name}
price={price}
count={review_count}
image={img_urls}
/>
);
})}
{goods.length % 3 === 2 ? <div className="buffer" /> : <></>}
</>
);
}
}
완성!!! 2탄 상세페이지에서 찾아뵙겠습니다.(--)(_ _) 꾸벅~