프로젝트 소개
- 미국의 스포츠웨어 브랜드 기업인 컨버스의 웹사이트 클론 프로젝트
- 프로젝트 기간 : 9. 14 ~ 9. 25 (2주)
- 개발인원 (총 6명) : 프론트엔드 (권영빈, 김호균, 문상호, 손병진) / 백엔드 2명 (강경훈, 김수정)
- 깃헙 링크 : 프론트엔드, 백엔드
주요 기능 (+영상)
1. 제품 상세 페이지
2. 장바구니
사용 기술
Front-End
- JavaScript(ES6)
- React.js (CRA, Class형 component 사용)
- Sass
- Git / Github
React 라이브러리
- React-router-dom
- React-slick (슬라이더)
내가 맡은 역할
나는 제품 상세 페이지와 장바구니, 그리고 미니 장바구니 일부를 담당했다.
제품 상세 페이지
- 상품 id 별로 데이터 불러와서 보여주기 (상품 세부 정보, 추천상품 등)
- 페이지 레이아웃 및 세부 SCSS 작업
- 사이즈, 수량 선택 후 장바구니 버튼 클릭시 미니 장바구니 및 장바구니로 데이터 전송 (장바구니에 없는 제품일 경우 신규 추가, 있을 경우 수량 추가)
- 동적 라우팅 사용하여 추천상품 클릭시 페이지 이동
장바구니 페이지
- 유저 정보 확인 후 백엔드 서버에 저장된 장바구니 데이터 불러와서 출력
- 삭제 버튼으로 장바구니 상품 삭제 기능
- - / + 버튼으로 장바구니 상품 수량 변경 기능
- '장바구니 비우기' 버튼으로 장바구니에 있는 제품 일괄 삭제 기능
- 장바구니 하단의 새로운 추천상품 표기
미니 장바구니 페이지
- 유저 정보 확인 후 백엔드 서버에 저장된 미니 장바구니 데이터 불러와서 출력
- 장바구니와 동일한 기능 추가 (신규 추가, 수량 변경, 제품 삭제 등)
잘한 점, 아쉬운 점
잘한 점
1. 11시 스탠드업 미팅 (매일)
우리 팀은 11시 스탠드업 미팅을 매일 가졌다. 온라인 상으로도 가능한 일이었지만, 생각보다 매일 아침 자신의 상황을 공유하는 것이 많은 도움이 됐다고 생각한다. 1차 프로젝트 이기에 각자의 기능을 구현하는 것에만 너무 치중할 수도 있기 때문에, 서로의 진행 상황을 자주 공유하는 것이 좋았다.
2. 열정러들
다른 팀들 모두 다 열정적이었지만, 우리 팀은 마지막까지도 새로운 기능을 넣어볼까? 이것도 해볼까? 라는 의견을 계속해서 공유했다. 그래서 발표 당일도 새벽 6시까지 팀원 전원이 남아 작업을 했다. 물론 오래 남아 있는다고 좋은 결과물이 나오는 것은 아니지만, 서로 독려하는 분위기가 있었고 그걸 부담스러워하는 팀원이 없이 모두 더 해보려고 했던 점이 인상 깊었다. (그럼에도 불구하고 하고 싶었는데 구현하지 못한 기능이 많았다..)
3. CRUD
가장 뿌듯했던 부분 중 하나인데, 장바구니 기능을 구현하면서 CRUD를 모두 경험해봤다는 것을 뽑고 싶다. 장바구니 제품 불러오기, 제품을 새로 추가, 장바구니 제품 수량 변경, 장바구니 제품 삭제 등을 모두 한번 (미니 장바구니까지 두번..)씩 구현해보았다는 것이 좋았다.
아쉬운 점
1. 나
나만 월요일 마다 출근을 하게 되어서, 해당 주의 리듬을 찾는 것이 생각보다 어려웠던 것 같다. 월요일 오후에 헐레벌떡 출근하니 체력적으로 힘들었고, 집중력을 찾는 것도 오래 걸렸다. 다행히도 추석 연휴 기간 동안 리프레시 할 시간이 생겨서, 배웠던 것을 재점검해보는 시간으로 사용하려고 한다.
2. 세부적인 기능 구현
사이트를 처음부터 끝까지 똑같이 따라해보는 것도 중요하지만, 사용자의 사이트 방문 -> 구매까지 이어지는 흐름을 모두 구현해보는 것도 중요하다고 생각한다. 첫 프로젝트이다 보니 각자 맡은 부분의 세부 기능 (애니메이션 등등)을 구현하는 것에 조금은 더 집중한 측면이 있었다. 구매하기 기능은 시간이 없어 구현하지 못했는데 추후 프로젝트에서는 이러한 기능들도 시도해 보고 싶다.
3. 동적 라우팅 좀 더 공부
동적 라우팅을 통한 페이지 전환에 대한 개념을 좀 더 공부하여 자유자재로 사용하고 싶은데, 아직은 익숙치 못한 것 같다.
다음 프로젝트 때는?
1. 리액트 라이프 사이클의 추가 메소드들 적용
componentDidMount() 외에, 컴포넌트의 업데이트시 수행하는 메소드인 componentDidUpdate()를 적용해보려 했는데, 생각보다 잘 되지 않아서 일반 함수로 대체하여 사용했다. 다음 프로젝트 때는 update 관련 메소드도 사용해보고 싶다.
2. 라이브러리 사용
기능과 맞는 것이 없어 리액트 라이브러리를 사용할 기회가 없었다. 모달이나 슬릭과 같은 라이브러리를 사용해보고 싶다.
3. 사용자 인증?
페이스북, 구글 로그인과 같은 기능을 구현해보고 싶다.
기록하고 싶은 코드
1. 첫 통신
componentDidMount() {
fetch(`${secondAPI}/products/${this.props.match.params.id}`)
.then((res) => res.json())
.then((res) => {
if (res.product_information) {
this.setState({
productId: this.props.match.params.id,
productInfo: res["product_information"][0],
});
} else {
console.log("제품 정보 가져오기 실패");
}
});
}
상품 상세 페이지에 접근할시 제품 id 별 데이터를 가져와서 보여주는 코드였다. 단순하지만 첫 통신 코드였고, 데이터를 가지고 세부 자식 컴포넌트에 보내주면서 props와 state 개념을 좀 더 확실히 알 수 있었다.
2. 장바구니 데이터 가져오기
componentDidMount() {
const { userToken } = this.state;
let totalPrice = 0;
let totalDiscountPrice = 0;
let finalPrice = 0;
Promise.all([
fetch(`${secondAPI}/orders/cart`, {
headers: {
Authorization: userToken,
// Authorization: localStorage.getItem("access_token"),
},
}),
fetch("http://localhost:3000/data/ProductDetail/CartPageRecommend.json"),
])
.then(([res1, res2]) => {
return Promise.all([res1.json(), res2.json()]);
})
.then(([res1, res2]) => {
for (let i = 0; i < res1.cart_list.length; i++) {
totalPrice += res1.cart_list[i].price * res1.cart_list[i].quantity;
totalDiscountPrice +=
res1.cart_list[i].price * (res1.cart_list[i].discount_rate / 100);
finalPrice = totalPrice - totalDiscountPrice;
}
this.setState({
cartItems: res1.cart_list,
totalPrice: totalPrice,
totalDiscountPrice: totalDiscountPrice,
recommendProducts: res2.CartPageRecommendItems,
finalPrice: finalPrice,
});
});
}
장바구니 페이지에서 한 번에 두번의 fetch를 사용해야 했고, 멘토님의 도움을 빌려 Promise.all을 통해 동시에 두 promise를 리턴받았다. 구글링을 통해 문제 해결 방법을 찾아서 여쭤보니 실제로 내가 찾은 방법을 사용하면 좋다는 이야기를 들었고 실제로 적용했기 때문에 많이 기억에 남았다.
3. 추천 상품 컴포넌트 재활용
<section className="cartProductRecommend">
<ProductDetailRecommend productInfo={recommendItems} />
</section>
간단한 코드지만 리액트 재활용성의 장점을 제대로 느낄 수 있었던 부분이었다. 상세 페이지의 추천 상품 컴포넌트를 전혀 상관없는 장바구니에서 불러왔고, 불러오는 다른 데이터를 productInfo라는 공통 props에 지정해주면서 형식을 그대로 가져올 수 있었다. 추가로 카트 추천상품에서만의 scss를 적용하여 비슷하지만 미묘하게 차이가 있는 부분을 효율적으로 구현할 수 있었다.
마치며
첫 프로젝트였고, 2주 전보다 많은 기능을 구현해보면서 자신감을 가질 수 있었다. 작업을 진행하면서 기본 개념의 중요성에 대해서 더 뼈저리게 느끼게 되었다. 꼭 프로그래밍 뿐만 아니라, 기본기를 무시하고 지나칠 경우, 많은 비효율성으로 이어질 수 있음을 항상 인지하고자 한다.
'프로그래밍' 카테고리의 다른 글
React 9. Hooks (useState & useEffect) (0) | 2020.10.04 |
---|---|
React 8. setState, this.props.children (0) | 2020.09.29 |
React 7 - Component Lifecycle (0) | 2020.09.26 |
wecode +37 (9/23) (0) | 2020.09.23 |
wecode +35 (9/21) (0) | 2020.09.22 |
댓글