커머스 사이트 "마담주" 클론 프로젝트

김현재·2021년 9월 13일
1

Projects

목록 보기
4/6
post-thumbnail

Project Overview

프리미엄 과일 부티크 커머서 사이트인 "마담주"를 클론코딩 해보았습니다!

Frontend Github Repository>>

Backend Github Repository>>

제작기간

21.08.30 ~ 21.09.10

구성원

FE : 김현재(me!), 정행운, 조성환

BE : 김장호, 최현수

기술 스택

FrontEnd

JavascriptReact(CRA)React-router-DOMSCSS

BackEnd

PhythonDjango,MySQLAqueryToolRESTful APIbcrypt,

Common

POSTMAN

Communication

SlackZoomTrelloGithubGitNotion

전체 구현 기능

  • 회원가입 / 로그인
  • 메인페이지 (me!)
  • 리스트페이지 (me!)
  • 상세페이지
  • 장바구니페이지

주요 구현 기능

팀원들과 페이지 별로 역할을 분담해 기능을 구현했고, 내가 담당한 페이지는 ✅ 표시를 해두었다.

Main page

  • scroll이벤트 활용하여 동적 page 구현
  • carousel 구현

List page

  • Lifecycle method와 fetch API를 활용한 데이터 렌더링
  • Qurey string을 활용한 filter 기능 구현
  • Path parameter 및 query string을 활용한 동적 라우팅 구현
  • 무한 스크롤 페이지네이션 구현

Detail page

  • lifecycle method를 활용하여 수량, 옵션 선택 및 삭제 기능 구현
  • carousel을 활용하여 이미지 슬라이드 구현
  • query string을 활용한 동적 라우팅 구현

Cart page

  • query string을 활용한 동적 라우팅 구현
  • lifecycle method를 활용하여 수량, 옵션 선택 및 삭제 기능 구현
  • state로 상태관리 후 결제 시 fetch API 활용하여 서버에 전송 기능 구현

 Login page & Signup page

  • 동적 class 활용하여 모달 on/off 기능 구현
  • 유효성 검증 로직 추가하여 FE/BE 양측에서 유효성 확인하도록 구현

Navigation bar

  • 공용 component로서 navigation bar 구현
  • 정적 routing 구현
  • Login/out 상태 활용하여 연결할 component 구분

Footer

  • 공용 component로서 footer 구현

구현 결과

Mainpage


상단과 하단 부분에 carousel을 활용하였으며, scroll event 및 video를 활용하여 동적인 페이지로 구성해보았다.

구현 코드 보러가기 >>

Listpage


무한 스크롤 기능을 활용하여, 스크롤이 client view의 가장 끝 지점에 도달했을 시 자동으로 fetch받아올 수 있도록 구현하였다.
BE 측에서 pagenation URI를 페이지별로 분리해주셔서 (1페이지,2페이지 이런식으로) 보다 쉽게 로직을 만들 수 있었다✨

  state = {
    page: 1,
  };

// pagenation 전용 fetch - scroll 끝 지점에 도달하면 이 함수를 호출하여 추가 페이지를 fetch한다
  handlePageFetch = () => {
    if (this.state.page < 3) {
      fetch(
        `${PRODUCT_LIST_API}page=${this.state.page}&tag=${this.state.filter}`
      )
        .then(res => res.json())
        .then(items => {
          const fetchData = items;
          const mergeData = this.state.items.products.concat(
            ...fetchData.products
          );
          const newObj = { products: mergeData };
          this.setState({ items: newObj });
          console.log(this.state);
        });
    }
  };

  handleScroll = () => {
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollTop = document.documentElement.scrollTop;
    const clientHeight = document.documentElement.clientHeight;
    if (scrollTop + clientHeight >= scrollHeight) {
      this.setState({ page: this.state.page + 1 });
    }
  };

  componentDidMount() {
    this.handleFetch();
    window.addEventListener("scroll", this.handleScroll);
  }

// 페이지가 넘어가야될 경우에만 fetch 받아오도록 CDU활용
  componentDidUpdate = (prevProps, prevState) => {
    if (this.state.page !== prevState.page) {
      this.handlePageFetch();
    }
  };

배운 점

메인 페이지에 carousel이 2개가 들어가다보니 상당히 심적으로 챌린지였다.
역시 예상한대로 처음 carousel 구현에 20시간이나 소요되었다..🥲
그래도 역시 한번 만드니까 원리를 확실히 이해하게 되었고, 이후 하단 carousel을 만드는 것은 1시간?도 걸리지 않았다.
역시 이것저것 만들어보아야 속도가 붙는구나라는 것을 깨달았다.

lifecycle method을 보다 적극적으로 활용할 수 있게 되었다

처음에 무한스크롤관련 로직을 CDM하나로 해결하려고 했는데 역시 택도 없었다..🥲
첫페이지 fetch가 되지도 않은 상황에서 동시에 두번째 페이지를 받아 가공하는 로직을 짜놓으니..리액트는 자꾸 에러를 던질 뿐이었다.
CDU은 잘못 쓰면 컴퓨터가 무한 네트워킹에 빠지다보니 무서워서 최대한 안 사용하고 싶었는데..무한스크롤을 만들려면 피할 수 없는 존재였고..
어찌어찌 fetch함수를 두개로 쪼개고, 각 상황 별로 분리되어 fetch되도록 CDU안에 조건문을 사용하니 우려했던거에 비해 CDU는 이쁘게 작동하게 되었다✨
앞으로 CDU는 겁먹지 않고 사용할 수 있을 것 같다.

좋았던 점

양보다 질, 속도보단 방향

FE & BE가 공동의 목표를 잡고 세부 계획을 세우기 위해 초기에 다른 팀에 비해 시간 투자를 많이 했다.

처음에는 살짝 우려가 되었던 것이 회의를 많이하다보니 다른 팀보다 구현 진도가 많이 뒤쳐졌었기에 구현을 많이 못해낼까봐 우려되었었다.

허나 기초공사를 탄탄히 한 덕분인지 merge를 할때도 큰 conflict가 일어나지 않았고, backend 서버와 첫 통신을 할때도 fetch구조를 많이 고쳐야하는 등의 불상사가 일어나지 않았다.

이러한 자잘한 수정들이 생략되어서 오히려 후반기에 갈수록 구현 속도가 매우 빨라졌고, 결국 둘째주 수요일에는 큰 구현은 모두 완료하여 우리끼리 자체 study session을 진행할 정도로 "시간적 여유"와 "기능 구현"이라는 두마리 토끼를 모두 얻을 수 있었다.

우리들의 특별한 session

장호님의 제안으로 특별한 session을 개최하게 되었다. 이름하여 "FE & BE cross-study session"으로, 프론트엔드와 백엔드가 각자 어떤식으로 workflow가 이루어지는지를 공유하는 세션이다.

workflow뿐만 아니라, ERD 모델링 분석 및 파이선 view 해석하기, javascript fetch API로직 처리과정 등 FE, BE간 커뮤니케이션에 활용할만한 교양강좌(?)를 진행하여 각 분야에 대해 좀 더 자세히 이해하는 시간을 가졌다.

이 시간 덕분에 전체적인 project schedule을 어떻게 가져가야할지, 그중에서도 (내가 속한)FE는 어떻게 탄력적으로 스케줄을 대응할 수 있을지에대한 답을 약간 얻게 되어 매우 뜻깊은 시간이었다✨

아쉬웠던 점, 앞으로의 계획💪

앞서간 경우, 어떻게 해야할 것인가

리액트를 다른 팀원들 보다 조금 수월하게 사용한다고 판단했기에, 첫주에 내 작업을 다 끝내고 둘째 주에 팀원들을 도우며 부수적인 업무를 하는 것으로 계획을 세웠었다.

그러나, 내가 할 최소한의 일을 끝내자마자 긴장이 풀렸는지 체력적으로 매우 힘든 시간이 이어졌다. 체력적으로 힘들어지니 기존에 갖고 있던 텐션이 떨어졌고, 팀원을 단순히 support 하는 두번째 주가 지나갔다.

두번째 주가 끝나갈 무렵, 팀원들이 추가구현 하고 싶었던 내용을 적어둔 카드가 우연히 눈에 잡혔다. 두번째 주를 만약, 팀원들이 구현하고 싶었던 추가적인 요소들을 구현하는데 추가했으면 어땠을까 라는 생각이 들었다.

혹여나 하는 생각에 다른 팀원한테 해당 팀원의 추가구현 요소를 내가 시도해봐도 될지 물어보았는데, 예상과는 달리 "그럼 정말 좋지요!"라는 대답이 돌아왔고 그순간 '아차!'싶었다..남의 작업물을 건든다는 것이 부담스러워서 내가 맡은 파트가 아닌 곳의 추가구현은 최대한 건드리지 말아야지라고 생각했지만, 의외로 누군가는 그러한 도움을 반기기도 한다는 것을 너무 늦게 알았다.

이 경험을 양분 삼아, 다음 작업 때는 (혹시 팀원이 OK한다면) 팀원이 원하는 추가구현 사항을 내가 만들어 보아도 될지 보다 적극적으로 물어봐야겠다.

개인적으로 아쉬웠던 것

나의 장점이자 단점인 "빠른 판단"이 팀원들을 힘들게 하지 않았을까 라는 생각에 마음 한켠이 살짝 걱정된다.

다들 처음하시는거니까 천천히 보고, 이해할 여유를 충분히 드렸어야 했는데..다같이 해야만 하는 작업인데 내가 체력적으로 많이 부쳐서 빨리 끝내고 싶은 마음에 조금 서둘렀던 경향이 없잖아 있었던 것 같다(내가 다 해버린다거나..끝무렵의 마이크로매니징이나..)

공동 회고 세션에서는 팀원들이 내가 그렇게 해준게 도움, 의지가 되었다고 하지만..그건 거시적인 평가일 수도 있고, 순간순간은 살짝 불편하시지 않았을지 우려된다.

나의 그런 미숙한 모습도 덤덤히 받아주신 팀원 분들께 정말 감사의 마음 뿐이다. 그렇기에 경각심을 가지고 "정말 필요한 순간"을 제외하고는 팀원들을 의지하고 맡기자! (그리고 체력관리..필수..✨체력이 성격이 되지 않도록 하기)

profile
쉽게만 살아가면 재미없어 빙고!

0개의 댓글