-
[프리온보딩코스 과제 회고 #2] 상품 조회 이력과 필터링 그리고 랜덤 로딩하기🏄♀️ 원티드X위코드 프리온보딩코스 2021. 8. 1. 16:24
1. 과제 구현 사항
- 상품 목록 페이지(/)
- 상품 목록 리스트를 클릭하면 상품 상세 페이지로 이동하기
- 상품 상세 페이지(/productdetail)
- 상품 목록 페이지에서 상품 상세 페이지를 선택하면, 이력 데이터를 누적하기
- 동일 상품을 조회하는 경우, 이력 데이터를 최신 데이터로 갱신하기
- '랜덤 상품 조회' 버튼을 클릭하면, 현 상품을 제외하고 랜덤 로드하기
- '관심 없음' 버튼을 클릭하면, 랜덤으로 목록을 로드하기
- '관심 없음' 버튼을 클릭하면, 해당 상품은 이후 상품 상세에 노출되지 않게 하기
- 상품 조회 이력 목록 페이지(/recentlist)
- 매일 자정(00시) 최근 조회 이력과 관심 없는 상품 목록 초기화하기
- 별도의 페이징 처리하지 않고 데이터 전체 로드하기
- 필터링 기능(목록 상단에 위치)
- 브랜드 필터링 : 데이터에 존재하는 브랜드 목록으로 구성하고, 다중 선택이 가능하다.
- 관심 없는 상품 숨기기 체크박스
- 정렬 기능(선택 팝업)
- 최근 조회 순
- 낮은 가격 순
- 상품 클릭 시 '상품 상세 페이지'로 이동하기
- 관심 없는 상품 클릭 시 경고 메시지 노출하기 (해당 페이지로 이동 X)
2. 내가 맡은 파트
- [상품 상세 페이지]
- '랜덤 상품 조회' 버튼 클릭 시 현 상품 제외하고 랜덤 로드 기능 구현
- '관심 없음' 버튼 클릭 시 랜덤 로드 기능 구현
- [모든 페이지]
- HTML 마크업 및 CSS 스타일링
3. 구현 방법
내가 맡은 파트는 HTML 마크업과 CSS 스타일링, 그리고 상품 상세 페이지에서 랜덤 버튼 클릭이 눌리거나, 관심 없음 버튼이 눌렸을 때 랜덤하게 리스트를 다시 로드해오는 작업이었다.
우선 상세 페이지에서 '랜덤 상품 조회' 버튼이 클릭되었을 때 새로운 단일 상품을 하나 랜덤으로 로드하기 위해서는 상품 목록 페이지에서 상품 상세 페이지로 전체 상품 데이터를 전달해주어야 했다!
앞서 목록 페이지에서 상세 페이지로 라우팅하는 작업을 하셨던 팀원 분이 history.push 방식으로 구현을 하셔서 history.push의 파라미터를 활용해 state를 보내주는 식으로 작업을 하게 되었는데, history로 state 보내주는 작업은 처음인 데다가 이번에는 오직 Class Component를 활용하여 구현을 했어야만 했기에... Function Component만을 사용해왔던 나에게는 정말 청천벽력이었다...😓(이래서 예습은 철저히 해야... 유비무환....^_ㅠ....)
우선 구현을 하는 데에 있어 제일 고생했던 부분이, 상품 목록 페이지에서 상품 상세 페이지로 전체 json 데이터를 전달해주는 작업이었는데,
📂 src > components > common > ProductItem.jsx
history.push({ pathname: `/productdetail/${id}/${title}/${brand}/${price}/${disLike}`, state: { allProducts: allProducts }, });
이렇게 history의 파라미터로 state를 전달해주면서 보내준 후, 상세 페이지에서 state를 전달받는 것이 문제였다.... 분명히 맞게 쳤는데 console.log로 state를 아무리 찍어봐도 undefined로 전달이 되는 것이었다... ㄱ-....
근데 알고보니 this.props 다음에 .location을 적어주지 않아서 계속 불러오지 못했던 것........... 그도 그럴 것이...^^ history로 보내줬으니 당연히 location 내부에 있을 것인데.. this.props.state만 찍고 "왜 안 불러와져~!ㅠ" 이러고 있었던 것....(바보다 증맬.....) 다행히 길지 않은 사투 끝에 this.props.location.state를 알아냈고.. 그 이후부터는 순조로웠다..^^
📂 src > pages > ProductDetail.jsx
handleRandomClick = () => { // 받아온 allProducts(전체 상품 데이터) 객체와 product(현재 보고 있는 상품 데이터)를 state에 저장 const { allProducts, product } = this.state; // randomNum에 랜덤으로 불러올 상품의 index 번호를 저장 const randomNum = Math.floor(Math.random() * (allProducts.length - 1)); const { title, brand, price, disLike } = allProducts[randomNum]; // 새롭게 불러올 랜덤 상품의 index 번호가 현재 상품과 동일하거나 // '관심 없음'인 경우 랜덤한 새로운 상품을 불러오게 분기 처리 if (`prod${randomNum}` === product.id || disLike) return () => this.handleRandomClick(); // history.push를 하여 랜덤한 새로운 상품을 불러오기 history.push({ pathname: `/productdetail/prod${randomNum}/${title}/${brand}/${price}/${disLike}`, state: { allProducts }, }); // 현재 경로의 데이터를 받아 상품 상세 페이지에 뿌려주기 const productData = getProductData(this.path); this.setState({ product: productData, }); };
하울의 움직이는 성 같은 나의 코드도 너그럽게 merge해 준 우리 팀원 분들께 심심(甚深)한 감사의 말씀을 전합니다...😊💚
4. 결과 화면
🔗 과제 배포 링크
5. 과제 회고
5.1 새롭게 알게 된 것🆕
1. 'Co-authored-by: Bohyun Kang <bohyunkang@users.noreply.github.com>'라는 메시지와 함께 커밋하여 협업하였다는 것을 커밋 이력에 남길 수 있다!
이번에도 우리 조는 페어로 과제를 진행하였다. 나중에 merge를 할 때에 있어 코드적인 충돌이 일어나는 경우를 방지하기 위함이었는데, 유기적으로 연결된 파트를 맡은 사람들끼리 각자 기능 개발을 하되! 같이 변수명이나 props 및 state에 대해서 논의하며 함께 작업하였다! 그래서 merge도 conflict 없이 완전 잘 되었다!(우리들의 빅픽쳐 대성공,,😁)
더욱 신기했던 건 의도하고 작업을 한 것은 아니었지만, 작업을 다 하고 돌아보니 네 명 모두 돌아가면서 함께 페어로 작업이 진행했다는 점이다!!
- 다은님과는 HTML 마크업과 CSS 스타일링을 함께 작업! 🎨
- 남주님과는 목록 페이지 & 상세 페이지 기능 구현을 함께 논의하며 작업! 👩💻
- 현찬님과는 브랜치 merge 후의 리팩토링 작업을 함께 하였다! 🛠
그렇기 때문에 페어로 함께 작업을 한 경우에는 커밋이 애매한 경우가 있었다. 근데 live share로 함께 작업을 하다 보니 비주얼 스튜디오 코드 commit 메시지를 입력하는 창에 'Co-authored-by: 깃허브이름 <깃허브아이디@users.noreply.github.com>'가 자동으로 입력되어 있었고, 이를 통해 commit을 남겼더니 아래 사진과 같이 함께 작업한 팀원의 프로필까지 같이 커밋에 남았다!
이번에 처음 알게 되었는데 앞으로도 페어 프로그래밍을 할 때마다 아주 유용하게 사용할 수 있을 거 같다!👍
2. 옵셔널 체이닝
이번에 처음으로 옵셔널 체이닝에 대해 알게 되었는데, 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있게 하는 기능이다! 우리도 이번에 총 3개의 컴포넌트에서 옵셔널 체이닝 기능을 활용하였다!
- ?.의 왼쪽 평가 대상이 null이나 undefined인지 확인하고, null이나 undefined가 아니라면 평가를 계속 진행한다. 만약 그렇지 않으면 undefined를 반환한다.
🔗 도움을 준 링크 : https://ko.javascript.info/optional-chaining
5.2 이번 과제를 통해 느낀 점🤔
[우리 팀이 이번 과제에 특별히 신경을 쓴 부분!]
- Github issue 활용한 task 관리
- ErrorBoundary를 활용한 에러 처리
- utils 함수 생성 및 관리
- Figma 활용한 프로토 타입 UI 디자인
지난번 과제는 2명이서 진행하여 1:1로 협업을 하다 보니, 의견을 취합하는 과정이 비교적 단순했던 반면, 이번에는 4명이서 협업을 하게 되니 의견이 4개가 되어 의견 취합하는 과정이 좀 더 다양해졌다! 그럼에도 불구하고 우리 팀(a.k.a 7ill Resource)은 정말 성격들이 다 좋아서 다들 유쾌하게 의견을 주고받을 수 있어서 좋았다!ㅎㅎ👍 또, 협업하는 과정을 한눈에 볼 수 있게 Github issue 탭을 활용하여 task를 관리하였다!
그리고 이번 과제는 지난번 과제와 달리 UI 디자인이 따로 제공되지 않고 구현 사항만 텍스트로 전달받았기 때문에 결국 모든 해석은 우리 몫이었다! 그러다 보니 하나의 문장을 가지고도 정말 다양한 해석이 나왔고,,,, 이걸 정확하게 논의하고 정리하여 개발을 해내는 것이 이번 과제의 관건이었던 거 같다..!(내 기준ㅎㅎ)
그래서 남주님의 주도 하에 피그마를 사용하여 UI 디자인과 구현해야하는 기능들을 정리하였고, 덕분에 더 간결하고 명쾌하게 우리의 To-do를 정리할 수 있었다! 나는 피그마를 사용해야겠다는 생각조차 떠올리지 못했는데, 피그마를 딱 들고 오셔서 기능 정리와 UI 디자인 착착 정리해주신 남주님(@skawnkk)... 정말 히트다 히트... 🤗💪💙
🔗 Figma 링크
맨처음에 과제를 받고, "이거 진짜 이틀 안에 구현할 수 있는 거 맞아..?"하고 너무 아득했었다..(ㅠㅠ) 밤잠 줄여가며 새벽 5시까지 작업하고 5시간 겨우 자고😪 10시에 다시 모여서 작업하고... 그야말로 정말 터프했던 이틀이었다.....😵 더군다나 다은님(@daeun-react)은 이 코스를 시작하기 전부터 계획된 가족 행사로 토요일에 지방 내려가셔야 했는데, 가는 길의 고속도로에서 테더링으로 Gather에 들어오신 열정... 정말 세븐이 와도 못 말리는 열정이었다...☆★ 우리 팀 이틀 동안 진짜 진짜 수고 많았다!! 역시 노력하면 안 되는 거 없다는 걸 진짜 이번에 다시금 깨달았다,,,,, 역시 인생은 어려워야 제 맛(?)~🧡
▼ 이번 과제의 한 줄 요약: 쉽살재빙,,~
'🏄♀️ 원티드X위코드 프리온보딩코스' 카테고리의 다른 글
[프리온보딩코스 과제 회고 #3] 권한 관리와 대시보드 그리고 유효성 검사 (0) 2021.08.08 [프리온보딩코스 주간 회고 #1] 치료가 필요할 정도로 심각한 '블로그 중독증'입니다. (4) 2021.08.02 [프리온보딩코스 세션 회고 #2] React Foundation과 첫 번째 과제 리뷰 (5) 2021.08.02 [프리온보딩코스 세션 회고 #1] 취업 성패를 결정하는 Business Manner (2) 2021.07.28 [프리온보딩코스 과제 회고 #1] 무한 스크롤(Infinite Scroll) (0) 2021.07.27 - 상품 목록 페이지(/)