찬란했던 1차 그룹 프로젝트 후기 @ WeCode

Jessica Lee
11 min readApr 24, 2021

벌써 위코드의 부트캠프를 시작한지 6주가 지났다. Foundation 코스를 마치고 4월 12일 부터 23일까지 2주간 첫번째 팀 프로젝트를 진행하고 어제 프리젠테이션을 마쳤다. 오늘은 이번 2주간의 기간을 회고하는 시간을 가지며 블로그를 작성해 보려고 한다.

프로젝트를 시작하며

이번 프로젝트 후기를 본격으로 이야기 하기에 앞서, 프로젝트를 시작하기 직전 주말에 일어났던 일은 나에게 개인적으로도, 다른 사람들과 같이 공부하는데에도 엄청난 변화를 끼쳤다. 정말 안타깝게도, 최측근 중 한 명이 코로나 밀접 접촉자라는 사실을 알게되었고, 결국 확진의 소식을 월요일 아침에 받아야 했다. 난 2주간의 격리가 불가피한 상태였고, 이것이 이번 프로젝트 첫날의 아침에 일어난 일이였다. 처음에는 정말 멘붕이였고, 주말 내내 걱정되어 잠이 오지 않았다. 이 상황이 원망스럽기도했다. 왜 하필 지금 ㅠㅠ…

하지만 그렇게 화나있을 시간이 없었다. 이미 일어난 일은 어쩔수 없고, 이 일이 프로젝트의 결과 그리고 팀원들에게 영향을 주지 않도록 최대한 열심히 하는것 밖에는 딱히 할 것이 없었다. 그리고 지금은 벌써 2주가 흘렀고, 이 2주를 통해 난 기술적뿐만 아니라 정신적으로도 엄청난 성장을 한 것 같다. 그것에 대해서는 마지막에 쓰겠다.

프로젝트 소개

어쨌든, 아침에 위코드에 소식을 알리고, 난 집에서 팀 발표를 받았다. 우리의 팀은 총 6명! 동이님, 준형님, 승찬님, 영훈님, 정현님이였다. 난 팀원들 중 가장 잘 알았던 동이님께 내 소식을 먼저 알리고 동이님은 그날부터 나와 끝이없는 구글밋의 굴레에 빠져들게 되었다…ㅋㅋ

우리가 클론하는 프로젝트는 마켓 컬리였다. 마켓 컬리는 국내 식품 온라인 쇼핑몰로 가장 유명한 브랜드 중 하나다. 우리는 바로 구글밋을 켜서 회의를 시작했다. 일단 어떤 페이지와 기능을 구현할 수 있을지, 하고싶은지에 대해 이야기 하였다. 시간이 2주밖에 없어서 모든 기능을 구현할수는 없기 때문에 가장 기본부터 시간이 허락하는 내에서 추가적으로 구현하고 싶은 기능들을 정리하였다. 또, 팀이름을 정하였다. 이름은 마켓 쵸컬리(Market Cho-Kurly)! 우리는 마켓 컬리에서 간식, 과자, 떡 카테고리 중 초콜릿, 젤리, 캔디의 부분을 구현하기로 해서 동이님의 센스로 나온 찰떡같은 이름이다.

역할 분담과 구현한 기능

우선 너무 감사하게도 팀원들이 나에게 PM의 자리를 맡겨주었다. 나는 PM을 해본적이 없기도 했고, 격리 중인 상태에서 좀 걱정이 되긴했지만 이것 또한 못해볼 경험이라고 생각하고 열심히 해봐야겠다고 다짐했다.

우리가 기본적으로 구현할 페이지는 크게 메인 페이지, 상품 리스트 페이지, 상품 상세 페이지, 로그인, 회원가입, 장바구니였다. 프론트 멤버들은 모든 페이지에서 사용되는 상단 헤더, 어사이드, 푸터를 프론트 멤버들 각각 하나씩 나누기로했다. 솔직히 뭘 맡아도 다 어렵고 배울점이 많을것 같아서 공평하게 사다리 타기로 역할을 분담했다. 나는 상단에 들어가는 네브 바, 메인 페이지, 상품 리스트 페이지를 맡게 됐다.

네비게이션 바

우선 공통으로 사용될 컴포넌트인 상단 네비게이션 바부터 시작하였다. 먼저 레이아웃을 HTML, SASS를 사용하여 짜고, 기능으로 넘어갔다. 네브 바는 들어가는 기능이 많지 않았다. 전체 카테고리에 마우스 올리면 카테고리 리스트가 나타나고, 카테고리에 또 마우스를 올리면 서브 카테고리가 나타나는 식의 기능이 가장 큰 것이였다. 난 이 기능이 생각보다 빨리 끝날 것이라고 생각하였지만 아주 잘못된 생각이였다. 이 기능만 3일을 고민하였고, 이것 저것 해보다가 도저히 시간만 지체할 수는 없어서 멘토님에게 힌트를 받아 겨우 성공 할 수 있었다. 이 코드는 밑에 정리해 보겠다.

메인 페이지

메인 페이지에는 크게 두,세가지의 기능이 있었다. 첫번째는 자동으로 넘어가는 캐러셀이였다. 페이지 상단에는 하나의 사진이 가로 전체를 덮고 약 5초에 한번씩 자동으로 넘어가고 화살표 버튼으로도 작동할 수 있다. 메인 페이지의 나머지는 모두 네개씩의 상품 사진이 한 프레임에 담겨 넘어가는 캐러셀로 구성되어 있었다. 신상품, 알뜰 상품 등 총 6개의 품목에 따라 각 캐러셀에 상품들이 담겨 보여진다. 그리고 중간에는 24시간 한정 세일을 하는 상품이 소개되며, 이 곳에 타이머를 추가로 기능을 구현하였다. 타이머는 생각보다 빨리 구현하였고, 캐러셀은 초반에 좀 고생을 하였다. 라이브러리를 사용하지 않고, 직접 하려다 보니 어려웠던 것 같다. 또, 하나의 사진만 보여지는 캐러셀에서 네개를 한번에 보여주는 것으로 적용을 하려니 조금 헷갈렸지만 네브 바 보다는 쉽게 구현하였다.

메인 페이지에서는 크게 네브 컴포넌트, 슬라이드 컴포넌트, 상품 카드 컴포넌트, 그리고 태그에 따라 필터링이 들어가야 해서 사용했던 태그 컴포넌트가 있다.

상품 리스트 페이지

상품 리스트 페이지에서는 크게 서브 카테고리로 상품 리스트를 필터링 기능, 신상품과 가격순으로 필터링 기능, 장바구니 아이콘을 누르면 띄워지는 모달 창, pagination 등이 있었다. 메인의 캐러셀에서도 사용했던 상품 카드 컴포넌트를 그대로 사용하였고, className에따라 사이즈를 조정해 주었다. 또 동적 라우팅을 이용해서 필터링된 데이터를 불러와 보여주었다. 장바구니 모달 창도 한번도 해보지 않은 기능이여서 재밌었고, 동적 라우팅을 통해 다른 데이터들이 불러오는 기능을 구현한것도 뿌듯했다.

협업 과정 그리고 Scrum

우리는 매일 아침 11시 10분에 모여서 daily standup meeting 을 하였다. 내가 학원에 가지 못했기 때문에 항상 구글밋을 키고 팀원분들이 모여 미팅을 진행하였다. 어제 마친 작업들을 서로 업데이트하고, 오늘 할일을 정리해 보고, 진행을 더디게 하는 blocker 가 있다면 공유하였다. 미팅이 너무 늘어지지 않게 신속하게 진행하고 바로 할 일로 넘어갔다. Trello에 카드들을 업데이트 하면서 우리가 지금까지 한 것들, 진행중인 것들, 아직 못한 것들을 한눈에 보게 해주었고, 영훈님이 센스있게 daily standup meeting 의 내용도 Trello에 올려주셨다. 바쁘다 보면 제때 업데이트를 안할 때도 있었지만 나중에 done에 쌓여가는 카드들을 보니 우리가 많은걸 했구나, 어떤것은 못 했구나를 알수 있어 좋았다.

기억에 남을 코드

카테고리 메뉴

이 코드는 가장 고생했던 기능 중 하나인 마우스 호버로 카테고리를 나타내는 기능이였다. 우선, 백엔드에서 받아오는 데이터는 각 메인 카테고리안에 서브 카테고리의 리스트가 담긴 array안에 array가 있는 형식이였다. map 메소드를 두번 써야할 것 같다는 것은 감이 왔지만, 어떻게 하면 하나의 메인 카테고리에 마우스 호버를 했을때 그것에 해당되는 서브 카테고리만 보여지게 하는가였다. 이런 저런 방식을 시도하다 시간이 너무 지체되어 멘토님의 힌트를 받았다. 우선 메인 카테고리에 onMouseEnter 핸들러를 사용해 id 를 categoryIdx 스테이트에 저장해주고, isSubOpen 스테이트를 true 로 바꿔준다. 그리고 조건부 렌더링을 통해, 데이터의 인덱스 + 1과 categoryIdx 가 같은지, isSubOpen 가 참인지의 조건을 달아 만족될 시 해당 서브 카테고리를 map 메소드를 통해 보여주었다.

캐러셀

이 코드는 메인 페이지에서 사용된 캐러셀을 구현한 코드이다. 자식 컴포넌트인 ProductCard 컴포넌트에게 상품 정보가 담긴 데이터를 map 메소드를 통해 전해주고 moveX 라는 x 축을 이동시키는 transform 스타일을 넘겨준다. 그리고 캐러셀 양쪽에 있는 버튼에 onClick 핸들러를 통해 함수를 실행시킨다. slideX 는 부모인 Main 컴포넌트에서 받아온 props 인데 한번 클릭에 몇개의 사진을 넘길 것인지에 대한 값이다. 총 네개의 사진이 하나의 틀에 보여지는 상태에서 2 이면 두개가 넘어가고 4이면 네개가 넘어가는 형태이다. goLeftgoRight 에서 x 축을 얼마만큼 넘겨줄것인지 설정해준다. 예를 들어, x가 0일때, 즉 맨 처음에 위치해 있을때는 왼쪽 버튼을 클릭해도 계속 왼쪽으로 넘어가면 안되므로 그 조건을 달아주어 삼항 연산자를 이용해 setState 해주었다.

타이머

이 코드는 특정 날짜가 오늘부터 얼마나 남아있는지 시간:분:초 단위로 나타내주는 타이머 기능이다. 구글링을 통해 짤수 있었다. 리팩토링하기전에는 함수가 복잡해 보였는데 멘토님이 변수화 시킬수 있는 부분은 다 해주는게 좋다고하셔서 정리를 해주었더니 그전보다는 깔끔해 보여 맘에 든다.

const twoDigits = time => { return (time < 10 ? ‘0’ : ‘’) + time; };

이 함수는 시간 단위가 한자리 수 일때 ‘7’이 아니라 ‘07’ 의 식으로 표현되어야 하기 때문에 추가해준 간단한 함수인데 특히 기억에 남는다.

페이지네이션

마지막으로 페이지네이션에 사용한 함수이다. 버튼을 클릭했을때 fetch 되어야할 api주소에 state 와 parameter를 template literals 를 사용해 적용해줘서 해당되는 페이지가 렌더링 될수 있도록 해줬다.

이루어낸 것들

우선 격리의 상황에서도 무사히 프로젝트를 마친 나에게 토닥토닥 해주고싶다. 그리고 꼭 이런 상황이 아니라도 개발은 리모트로 진행되는 상황이 아주 많을텐데 미리 경험해 보아서 오히려 좋았던 것도 있다. 개인적으로도 나의 최측근에게 이런일이 일어났다는게 정신적으로 힘들었는데 이렇게 잘 해내고 나니 내가 생각보다 나약한 사람은 아니구나(?) 라는 자신감이 생겼다 ㅋㅋㅋ 이제 무슨 상황에서도 프로젝트를 할수 있다는 자신감!

그리고 팀원들과의 소통, 팀워크도 아주 좋았다고 생각한다. 발표 마지막날, 거의 새벽 5시까지 구글밋 두개를 동시에 켜가며 (프론트 하나, 백 하나) 문제를 해결하고 마지막까지 불태우면서 최선을 다한 것이 힘들었지만 뿌듯하고 재미있었다. 백엔드 분들이 임의로 지으신 상품 이름들을 보며 집이 떠나가라 웃은것도 기억난다..ㅋㅋ 큰웃음과 센스 감사합니다.

지식적으로는, state 라는 개념에 전보다 훨씬 익숙해지고, 어떻게 하면 더 효율적으로 component를 사용해야할까 고민할수 있었다. 그밖에 이벤트 핸들러, 조건부 렌더링, 삼항 연산자, 동적 라우팅, 페이지네이션, 맵 메소드, 캐러셀 구현, 타이머 구현 등등 수많은 개념과 함수에 대해 배울수 있었다.

아쉬운 것들

처음에는 백엔드와 맞춰봐야 할때 시간을 상당히 소모해야했다. 나는 학원에 갈수가 없으니 백엔드의 서버랑 연결할 방법을 딱히 몰랐기 때문이다. 하지만 멘토님이 알려준 live share 라는 VSC의 익스텐션을 사용해서 떨어져있어도 서버를 쉐어 할수 있었다. 다만, 바로 옆에 있지 않으니 서버가 꺼지거나 문제가 생길때 신속하게 해결할수 없었던 점이 조금 답답하기도 했다. 그래도 전체적으로 수월하게 진행되었다고 생각한다.

좀 더 꼼꼼하게 구현하고 싶었던 기능들도 몇가지 있다. 상품 리스트 페이지에서 신상품순, 가격순으로 sorting 을 해주는게 있었는데, 처음 클릭할때는 실행이 안되는 문제가 있었다. 그리고 검색창을 통한 필터 기능도 추가적으로 구현하고 싶었지만 시간상 하지 못했다. 다른 팀원들이 맡아준 장바구니 페이지도 백엔드와 맞추면서 코드 수정이 많았는데 모두가 붙어서 마지막까지 해결해보려고 했지만 미흡한 점이 있었다. 시간관리, 처음 계획 단계에서 어떤 컴포넌트들이 서로 연결되는지에 대한 이해, 백엔드와의 데이터에 대한 계획과 소통이 참 중요하다는 것을 깨달았다.

프로젝트를 마치며

우선 프로젝트는 정말 팀과의 소통이 중요하고, 혼자는 할수 없다는 것을 다시 한번 깨달았다. 나의 상황을 이해해주고 배려해준 팀원들이 고마웠고, 불평하지 않고 서로 하나의 목표를 향해 각자의 맡은 바를 최선을 다해 이뤄준 점이 감사했다. 또 멀리있는데도 도저히 해결안되는 기능들이 있을때마다 도와주신 멘토님들도 너무 너무 감사하다.

처음에는 나만 떨어져 있어서 더 힘들거라고 생각했는데, 오히려 이런 경험으로 나만의 스토리를 만들수 있다는 생각으로 열심히 했다. 그래서 더 뿌듯하다. PM 으로서 뭔가 특별하게 더 한것은 없다고 생각하지만 미팅을 더 이끌어가고, 질문을 하고, 서로 업데이트를 신속하게 하도록 노력했다. 우리 팀 모두 최선을 다해서 자랑스럽고 다음 프로젝트때는 이번에 느낀 점들을 참고해서 더 좋은 과정과 결과를 만들기를 바래본다.

--

--