[Project] motemote 클론 코딩 회고록

hojung choi·2021년 8월 13일
4

Project

목록 보기
1/1
post-thumbnail

🔥 motemote 클론 코딩 회고록

위코드에 들어온지 한달이 되던 날, 우리는 1차 프로젝트를 시작했다. 불과 한달 전까지만해도 for문 if문을 겨우 돌리는 우리였는데,, 플젝을 시작하라니 ... 😱 역시나 예상대로 처음엔 우여곡절도 많았고 너무 힘들었다 하지만 너무너무너무 얻은게 많은 나의 첫 플젝 🥺




✍🏻 1차 Sprint

조 편성이 발표 됐고, 우리는 곧장 만나 사이트를 확인했다.
사실 모트모트 사이트를 나현님 발표때 들어보긴 했는데 그 때 들은 것을 제외하면 초면인 사이트였다.
모트모트는 문구류를 파는 쇼핑몰이었고 flow는 딱 기본적인 쇼핑몰이었다.



우선 내가 빨리 쳐낼 수 있는 css 요소가 대부분인 nav,footer를 맡았다.
실제로도 멘토님들의 빠른 피드백과 수정, merge가 이뤄졌다.


👉🏻 Mian

1. 슬라이드 구현

  • 라이브러리 slick을 써서 구현했었다! slick는 퍼블리셔때 많이 써봤던 라이브러리라 음,, 다를게 없네,, 쉬운데? 하고 썻는데 라이브러리는 1차때 쓰면 안된다는 사실을 뒤늦게 알았다 ^^ ㅎㅎㅎㅎㅎㅎ 부랴부랴 로직을 짜기 위해 노트와 펜을 꺼냈던 기억이... 로직이 그렇게 어렵지 않아 큰 이슈없이 구현했던 기능이다.

2. BEST ITEM

  • Best Item api를 fetch를 통해 받아와 뿌려줬다
  • 조건부 랜더링을 통해 할인금액이 있으면 밑에 빨간색으로 할인금액을 표출시켰고 원가에는 line-through를 주어 삭제(?)처럼 표출시켰다
  • 조건부 랜더링을 통해 stock(재고)이 0일 경우 sold out라벨을 표출시켰다.
  • 이미지는 master가 어떤 비율로 올릴지 모르니까, 이미지가 비율대로 줄어들 수 있도록 css를 적용시켰다. (참고로 이 코드는 내가 퍼블리셔때부터 자주 쓰던 코드이다! 좋은건 나눠쓰기! 저한테 찾아오면 코드 설명을 자세히 해드리겠습니다 😇)

👉🏻 ProductList

3. Product List

  • BestItem에 있던 레이아웃과 동일!
  • color filter를 api로 받아오는 것이 아니는 해당 컬러가 display:block, display:none이 되도록 코딩하였다.
  • 자세한 설명은 아래에서 하겠다!!!



✍🏻 2차 Sprint

1차 스프린트가 금요일날 끝나고, 나는 주말내내 리뷰 post와 get을 위해 공부를 했다. 특히 이미지를 첨부파일로 올리는 방식을 하고싶었기때문에 form Data를 사용하여 로직을 짜놨다. form Data를 구글링 하던중 FileReader도 알게 되어 같이 공부를 했다. (back api가 완성 된 상태가 아니라 테스트도 못해보고 혼자 생각해서 로직을 짯어야 했다 🥺) 또한 axios도 같이 공부하여 fetch 대신 write에는 axios를 사용했다.


생각보다 코딩이 너무 일찍끝나버렸다...ㅎ 처음에 리뷰를 하고싶었던 이유는 form data도 있었지만 완전한 CRUD를 하고싶었다. 그치만 아직 다른 팀원들은 작업중이기에.. 시간이 촉박해보여 나현님과 같이 장바구니를 하기로 하였다.
나현님이 레이아웃 및 컴포넌트는 전부 나눠놓으신 상태였고, 같이 get post path delete만 api통신을 하면 되는 상태였다.


👉🏻 Review


1. 리뷰 get

  • api의 결과 값에 따라 alert창을 띄워주었다. (리뷰 권한이 없습니다!,로그인 후 이용해주세요!,이미 작성하신 상품입니다!)
  • 모든 조건이 맞았을 때 this.props.history.push을 이용하여 페이지를 이동하며 state에 itemId값을 들고 갔다
  • 모든 리뷰 리스트의 별점을 배열로 만들어 reduce를 이용하여 리뷰 평균 평점을 나타냈다

2. 리뷰 post

  • 별점을 onMouseOver와 dataset을 이용하여 마우스가 hover했을때 별점이 반응하도록 했고, 클릭했을때는 고정값으로 값을 넘겨주었다.
  • FormData를 이용하여 axios로 body를 보내주었다
  • 자세한 설명은 아래에서 하겠다!!!

👉🏻 Cart

1. 수량변경

  • 업,다운 버튼을 누르면 수량이 변경되며 총 결제 금액이 바뀐다.
  • 자세한 설명은 아래에서 하겠다!!!

2. 삭제

  • 삭제를 누르면 해당 아이템 삭제된다
  • 자세한 설명은 아래에서 하겠다!!!

3. 장바구니로 이동하는 팝업 문구

  • 만약에 장바구니에 해당 아이템이 있으면 "이미 있는 상품입니다. 장바구니에 추가하시겠습니까?" 해당 아이템이 없으면 "장바구니로 이동하시겠습니까?"라고 뜬다.
  • 여기에 대한 이야기도... 자세한 설명은 아래에서 하겠다!!!



✍🏻 우여곡절 우당탕탕 🤸🏻‍♂️

✅ git

브랜치에 익숙하지 않아 계속 한 브랜치에서 여러 작업을 하고 다른 브랜치로 옮겨갈때 기존에 브랜치에서 작업했던 작업물이 날라가는 일이 발생하였다 😱
다행이 간단한 css파일이라 금방 작업을 다시 했지만 다시는 이런일이 반복되면 안되니까... 온 사방에 🌟브랜치 확인 브랜치 확인🌟 이라는 문구를 써놓고 남은 플젝을 이어갔었다!


✅ Product List

🔥 1차 시도

state에 selectColor를 넣어 선택을 한 color가 selectColor에 넣어지게 했었다.
그렇게 했더니... state에 있는 selectColor가 모든 section에 적용이 되니 다른 section에도 해당 color가 적용이 되어 버렸다 🥺


🔥 2차 시도


무한 삽질을 하고 있었던 나에게... 성훈님이 state에 담는 color값을 배열로 받아 그 인덱스와 section Index가 일치하게 하면 되지 않을까요? 라고 힌트를 쓱 던져주고 사라지셨다..ㅎㅎ 다시 또 무한 삽질 중 드디어 됐다!!! 🧚🏻‍♀️


Array() 내장함수를 통해 원하는 배열만큼 길이를 만들어주고, fill을 통해 ''빈 값으로 배열을 만들었다. 해당 color를 클릭했을 때 clickColorDefault함수를 실행시켰다. clickColorDefault함수는 dataset을 통해 color값을 받아 오고, 그 컬러 값을 selectColorset의 인자값으로 sectionIndex값과 함께 넘겨준다.
selectColorSet은 배열의 불변성을 유지하기 위해 스프레드 연산자를 통해 새로운 변수에 복사를 해주고, sectionIndex 값에 color값을 넣어주고 setState을 해준다!


data-set의 활용을 처음 알게 해준 color Filter,,,! 사실 api를 받아와 get을 해주면 쉬운 작업이었겠지만 조금은 다른 방식으로 해보고 싶었다 (실무에서는 api을 받아와 뿌려주는 방식을 더 많이 쓰겠지...?ㅎㅎ)


✅ Review post

하나도 버릴 것 없는 코드,,,,, 🧚🏻‍♀️
정말정말 고생 많이 했던 코드다 🥺...


주말에 Form Data와 FileReader를 공부하며 작성했던 코드!
드디어 백과 맞춰보는 날...! 두근두근
500에러^~^ ㅎㅎㅎㅎㅎ
500에러가 떳어도 나는 안심하지 못했다 ㅠㅠ,, api문제가 큰 확률로 500에러가 뜨지만 양쪽 다 처음 하는 작업이기에 혹여나 내 잘못일수도 있기에 여기 저기 종성님 선호님과 함께 알아봤다. 알아본 결과! 나는 form Data로 데이터를 주고 있었는데, api에서는 json으로 받고있으니 이게 될리가 없었다 🤦🏻‍♀️
선호님과 종성님이 이틀동안 작업한 결과,,, 성공 🧚🏽‍♂️
셋이서 엑박이 아닌 사진이 뜨는걸 보고 소리를 질렀다 🥳 ㅎㅎㅎㅎㅎㅎㅎㅎ


정말 API의 중요성을 느꼈던 부분이었다. 내가 원하는 기능이 있는데 API가 없으면 어쩌지? 혹은 반대로 백은 API구현을 다 해놨는데 내가 그걸 앞에서 못받아주면 어쩌지? 라는 생각이 들었다. 내가 원하는 기능을 끝까지 붙들고 API를 만들어준 종성님과 선호님께 너무 감사한마음이 든다 👍🏻


✅ Cart 수량변경

나현님이 sos를 했던 수량변경 부분
문제상황
detail에서 수량이 정해져서 cart로 넘어오는데 up버튼과 down버튼을 눌렀을때 +1씩 total금액이 늘어나는 것이 아닌 +1을해도 detail에서 수량이 정해져 온 만큼 늘어나는 것이었다!


나는 index를 이용하여 내가 클릭한 이벤트 index와 같으면 그 객체의 수량만 up시켜주기 라는 로직이 떠올랐다.
map을 통해 아이템들을 출력시키고 있었기에 그렇게 클릭한 이벤트의 index를 찾았는데... 찾았는데.... 어떻게 +1시키지....?ㅎㅎ...
성훈님 sos!!!
"로직은 굳! 불변성을 지키면서 +1시키면 됩니다!"


나는 문득 종택님의 위스타그램 코드 리뷰가 생각났고! 그걸 활용해서 우리는 코드를 작성했다!


마지막으로 도현님이 +1과 -1함수가 같은데 합칠 수 있지 않을까요? 라고 말씀을 해주셨고 드디어 나온 최종코드 💫


✅ Cart 버튼이 왜 맘대로 작동하지..🤯

api를 호출 하려면 Index가 필요해 index를 인자로 받오는 함수였다.
버튼을 onClick을 하면 함수를 호출하도록 했고, 그렇게 했더니..... 왜 페이지가 로딩 되자마자 함수가 작동하는거지??? ()을 안쓰면 어떻게 하지?? 매개변수로 넘겨줘야하는데???? 😱


콜백에 화살표 함수를 사용하면 됩니다!!!!
정말 쓸모가 많을 것 같은 코드이다 🔥


✅ Cart 삭제

delete api는 뭐 삭제만 하면 되니까 쉽지~ 라는 나의 큰 착각...🌟


문제상황은 삭제버튼을 클릭하면 db에는 삭제가 제대로 실행이 되는데 우리 쪽에서는 다시 get을 해줘도 새로고침이 되지 않아 수동으로 새로고침을 해야하는 상황이었다! 이걸로 4시간을 붙잡고 있었다~~
이것때문에 점심도 안먹으려는거 선호님이 점심먹는데 데리고 가주셨다....


4시간을 삽질한 결과는 조금은 허무했다..(아니야 얻은게 많아.... 호정아)

.then(data => data.json())
.then(data => {
  this.getCartData();
});

처음에 작성했던 코드이다.
여기서 나는 대단한 착각을 했었다. 이거는 get이 아니라 post인데 then을 통해서 나는 뭘 받아오는데??? 왜 data를 json으로 파싱하고 있었지???
api에서는 성공을 해도 아무것도 보내주질 않는데... 왜냐구? post니까!! (MESSAGE를 받을 수 도 있지만 해당 api는 MESSAGE를 보내주지 않고 있었다...)


data를 받아오는 것이 아닌 status를 받아와 status가 204일때, get을 하는 함수를 실행하도록 로직을 바꾸었다.
정말 너무 힘들었던 4시간이었다... 🤯 중간에 울뻔했던건 비밀 ^-^


✅ Cart로 이동하는 팝업 문구

결과부터 말하자면 이 부분은 포기한 부분이다.. 🙇🏻‍♀️ (포기는 아니고.. 효율성을 위해.... 음...🤔)
결국엔 종성님과 선호님이 api에서 처리해주는 걸로 해주신 부분..


문제상황은 장바구니에 해당 아이템이 있으면 "이미 있는 상품입니다. 장바구니에 추가하시겠습니까?" 문구가 해당 아이템이 없으면 "장바구니로 이동하시겠습니까?"문구가 뜨고 이동하는 api uri도 달라 버튼도 각각 만들어주어야했다.
조건문을 통해 문구를 제어하면 쉽게 풀리지않을까? 라고 생각했었다.. 근데 왜 자꾸 반대로 뜨니....? 그럼 반대로 if문을 적자!! 응? 왜 텍스트랑 uri가 반대니...? 이 루트를 무한 반복 겪는데....
선호님과 종성님이 😇처럼 나타나 api에서 처리해주는 걸로 바꿔주셨다...
당장 내일이 발표라 해결된 것만 확인하고 넘어갔다


뒤늦게 확인을 해보니 부모 컴포넌트에서 map이 돌아가고 있고 자식 컴포넌트에도 조건부 렌더링이 걸려있는데... 이게 문제였을까...? 아무튼 해결과는 별개로 너무 아쉬웠던 부분이었다 🥺


✅ 동적라우팅

뭔가 그냥 멀리서 봤을때부터 어려워 보였던 동적 라우팅...
1차 스프린트때 연욱님께 한 5번 물어보고.. 도현님께도 3번정도 물어본 부분이다 ㅎㅎ 두 분다 2차 스프린트 가게되면 하게 될거라고 이야기 하셨지만
나는 그냥 얼른 해버리고 싶었다 .. 성격급한거 여기서 나오고.. ㅋㅋㅋ
그래서 1차 스프린트를 마무리 하며 내가 구현한 nav -> list, main->detail부분까지는 잡아 놨었다.


종성님이 주신 api명세서 보고 뚝딱 하니 너무 신기하게도 정말 뚝딱 하고 내가 원하는 화면이 나왔다 😱
그렇게 한번 물꼬가 트이니 2차스프린트 막바지에서도 동적 라우팅 부분에서 막힌 것 없이 술술 흘러갔다! (다른 부분에서 오류 폭팔이었지만 🔥)




📌 나의 첫 프로젝트를 마치며..

여기까지 회고록을 작성하는데 5시간 정도 걸린 것 같다..
그만큼 내가 배운게 많고, 느낀점이 많았다는거겠지?

처음 팀원이 발표 됐을때 다들 말을 몇번 해보지 않은 분들이 대부분이 었다.. 아니 대부분이 아니라 전부였다 😅
백분들과의 소통도 걱정을 많이 했었는데(아무래도 양쪽 다 처음인 상황이었고 백이 무엇을 원하는지, 어떻게 구현을 하는지 무지해 막연히 두려웠었다),
나현님의 리드로 충돌 한 번 없이 물 흘러가듯 흘러갔던 우리들의 첫 프로젝트

개인적으로는 힘들었던 시간도 있었다. 내 성격에 내가 스트레스를 받아 팀원들 앞에서 눈물을 보였던 일도 있었다. 나는 한 번 시작한 일은 끝을 봐야하는 사람이다. 그리고 기한이 정해져 있으면 무조건 그 전에 끝내놔야한다. 이러한 성격이 나한테 너무 큰 압박으로 다가온것같았다. 나는 욕심도 많아서 (이러니까 되게 못되먹은 사람같.... 아닌데...🥺) 코드가 깔끔했으면 좋겠고, 간결했으면 좋겠다 그런데, 기한이 정해져 있으니 코드를 정리 할 시간이 너무 촉박했다.
그런 시간이 있고 난 후 , 선호님이 "우리 금요일이 발표니까 수요일까지 기능구현 하는걸로 하고 그 이후로 안돼는 기능들은 그냥 깔끔하게 포기해요!" 라고 말씀을 하셨고 뭔가 나는 그때 이후로 마음을 비웠던 것 같다.. 내가 할 수 있는 능력치에서 최선을 다 하자고 그리고 그 외의 영역들은 다음기회에 도전하면 되니까! 개발자 한달하고 관둘거 아니니까!! 🥳 그렇게 1차 스프린트가 끝났고 2차 스프린트는 부담없이! 정말 개발을 즐겼던거 같다! (+나현님과 같이 장바구니를 구현해서 그런거일지도 ㅎㅎㅎ)

그렇게 부담없이 진행하다보니 결과물은 만족스러웠다! 우리가 발표할때 지선님이 "선배기수들꺼 리팩토링한거 아니죠?" 라고 말씀 하셨고 우리도 너무너무너무너무 만족했었다!!!

물론 아쉬웠던 부분들도 있었지만...

  • 컴포넌트 분리 (메인 베스트아이템과 productlist는 같은 컴포넌트를 써서 구현할 수 있지 않았을까)
  • 리뷰 수정/삭제 구현
  • fetch, axios 예외처리 등등...

리팩토링을 통해 몇몇개는 수정하겠지만 전체적인 로직이 바뀌는 일은 아무래도 오랜 시간이 걸릴것같다.

마지막으로 한번의 다툼 없이 2주동안 12시간씩 코딩했던 우리 팀원들 ❤️
2차 스프린트때는 로비에 6명이 거의 붙박이었다 ㅋㅋㅋㅋㅋㅋㅋ
다른 팀들이 우리가 없어 방이 너무 추웠다고...



1차 프로젝트 잘 놀다 갑니다 🔥🔥🔥🔥🔥

profile
🧚🏻‍♀️ Front-End Developer

3개의 댓글

comment-user-thumbnail
2021년 8월 15일

호정님 고생 많으셨어요 멋있습니다👍🏻👍🏻

답글 달기
comment-user-thumbnail
2021년 8월 16일

호정님🙂 호정님덕분에 너무너무 많이 배운 1차 프로젝트였습니다!! 덕분에 저도 즐겁게 프로젝트에 임했습니다:) (작은 바람이 있다면, 기업협업도 같이 갔으면 좋겠어용🤓) 고생하셨습니다~

답글 달기
comment-user-thumbnail
2021년 8월 17일

호정님! 호정님이랑 함께해서 1차 프로젝트가 더 알찼던거같아요!! 덕분에 여러가지를 시도해볼 수 있었고 정말 많은걸 배웠습니당 👏👏 호정님이라면 2차 프로젝트도 완전 뿌셔뿌셔 버리실거라고 생각해요 ㅋㅋㅋㅋㅋ

답글 달기