2주간의 1차 프로젝트 후기...

선릉맥주

2주간의 팀프로젝트가 끝나고 READMD 를 작성하니 이제 진짜 프로젝트가 끝났다는 실감이 났습니다.

저는 프론트엔드를 맡아서 진행하였고 진행했던 프로젝트는 제주맥주를 클론 코딩한 선릉맥주였습니다.

선릉맥주 프론트 주소 github 입니다.

유튜브 데모영상은 아래 메인 페이지를 클릭하면 들어가볼수있습니다.

프론트의 경우 리액트를 통해 프로젝트를 진행하였고 class형 컴포넌트를 사용하여 구현하였습니다.

적용된 기술의 경우 CRA를 통해 기본 기본 프로젝트를 설정하였고 주로 사용된 기술은 React, React Router, Sass 와 더부러 JavaSript 였습니다.

또 추가적으로 사용된 라이브러리는 Dompurify, React Daum Postcode 를 사용하여 필요한 기능을 구현하였습니다.

총 구현된 페이지는 메인, 로그인, 회원가입, 상품리스트, 상품상세, 장바구니, 결제하기 이렇게 페이지를 구현하였고 제가 구현한 페이지는 메인, 상품상세, 결제하기 페이지였습니다.

메인페이지

메인 페이지의 경우 위에 보이는 이미지와 같고 메인페이지의 경우 캐러셀 기능만 존재하였고 캐러셀을 리액트로 구현해보기는 처음이었기 때문에 개인적으로 어려웠던 작업이었습니다.

결국 원래는 화면전환시 부드럽게 전환하고자 하였지만 페이지 전환에만 초점을 두어 개발하게 되었고 페이지 전환부분을 구현하며 리액트에서 상태를 어떻게 관리할것인가 많은 생각을 하게되는 계기가 되었습니다.

초창기에는 각 페이지별로 선택했는지에 대한 상태를 각각의 메인페이지에서 가지고 그 상태값을 변화값을 주어 해당 아이디가 선택되었는지 확인을 하였다면 보다 직관적이도록 currentIndex: 0 라는 현재 선택된 배열의 인덱스 값을 통해 상태를 변화시켜 가져오는 방법으로 수정하여 현재위치, 이동할 위치, 선택할 위치등 위치변화에 보다 유연하게 대처할 수 있게되었습니다.

Before :
{
    "id": 1,
    "imgUrl": "주소",
    "imgAlt": "alt",
    "isSelected": true
 }
After :
currentIndex: 0 

상세페이지

메인페이지 이후 구현했던 상세페이지 입니다.
상세페이지에서는 react-router-dom의 동적 라우팅으로 상품의 아이디를 가져와 해당 아이디를 조회받아온 JSON 형식의 데이터를 state를 통해 상품상세내역을 가져왔고 아래의 상품설명을 innerHtml로 데이터를 처리하였습니다.

초기 react에서 innerHtml 처리를 어떻게 할지 고민하다 dangerouslySetInnerHTML 를 알게되었고 xss에대한 부분의 피드백을 받아 Dompurify 라는 라이브러리를 통해 아래와 같이 한번 필터를 걸쳐 html을 삽입하여 구현하였습니다.

상세페이지에서는 주로 쪼개진 컴포넌트내에서 어떻게 이벤트와 상태들을 관리할까에 대한 공부되었던것 같습니다.


class GoodsDetail extends React.Component {
  render() {
    const { goods, detailRef } = this.props;
    const desc = DOMPurify.sanitize(goods.description);

    return (
      <div className="goods-detail" ref={detailRef}>
        <div className="goods-wrapper">
          <div dangerouslySetInnerHTML={{ __html: desc }}></div>
          <GoodsInfo info={goods.info} />
          <DeliveryInfo />
          <Refunds />
        </div>
      </div>
    );
  }
}

Mock Data를 통해 개발할 당시에는 수량에 대한 이벤트 부분을 해당 컴포넌트에 두었으나 막상 변경된 이벤트에 적용되는 내용이 아래의 다른 컴포넌트에 필요하게 되어 상태와 상태변경 이벤트들을 적용되야하는 컴포넌트로 옮기는 작업을 진행하며 맨처음 컴포넌트를 나눴을때 분명히 알고있음에도 놓쳐서 한번하면 되었을 작업을 두번 진행하며 보다 컴포넌트 상태와 이벤트 위치에 대해 고민해보고 작업해야겠다는 생각을 들게 해주는 계기가 되었습니다.

결제하기

마지막으로 결제하기 페이지 입니다.
초반까지만 해도 결제하기 페이지는 어려울게 없을거라는 생각을 하고 진행하였으나 생각보다 복잡했던 체크로직들과 많들다보니 너무 많아진 상태와 이벤트, 그리고 함수들로 인해 어려웠었던 페이지였습니다.

초기 최종 결제금액에대한 수량과 총금액을 계산할때 reduce를 써봐야겠다는 생각을 했었고 이부분에서 reduce의 초기 설정값에 대한 함수의 이해도가 적어 어려움을 겪었습니다.

가격과 수량의 경우 배열안의 객체로 관리하고 있었고 기존 reduce를 공부할때에는 배열아래의 숫자타입의 형태만 써봤었기 때문에 객체로 들어오는 데이터의 초기값이 객체라는 사실을 생각하지 못해 reduce함수 내에서 최초 값의 typeof 함수를 통해 object 타입일 경우를 분기처리하여 최종결제금액을 계산하도록 구현했었습니다.
그러나 여기서 항목이 1개일 경우 바로 object타입을 반환하여 값을 제대로 참조하지 못하여 에러가 나는 상황에 직면했고 그때 다시 reduce에 대한 문서를 참고하여 해결하는 계기가 되었습니다.

var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
},initialValue)

console.log(sum) // logs 6

체크로직에 대한 부분은 필요한 부분의 상태를 관리하려고 하지 너무 많아지는 상태들과 체크하기 위한 함수들로인해 직관적으로 보기 어려웠던 점과 this.props.children을 사용하여 각각의 정보로 구현하려다 보니 결제하기 한페이지가 너무 많은 html 코드로 html화면이 직관적이지 않다는 것이었습니다.

보기 편하도록 또다시 컴포넌트를 쪼개는것이 좋을지 않좋을지 고민이 되었고 이부분에서는 토스ㅣSLASH 21 - 실무에서 바로 쓰는 Frontend Clean Code 라는 참고 자료를 통해 컴포넌트를 쪼개기로 결정하여 컴포넌트는 추가되었지만 보다 결제하기 페이지 자체 컴포넌트와 각각의 실제 동작하는 컴포넌트에서는 보다 직과적으로 처리할 수 있었습니다.

마지막으로...

프로젝트는 무사히 끝났지만 내가 그동안 알고있다고 잘못 생각했던 부분이나 내가 알고싶었던 기본적인 리액트의 state, props를 통한 상태관리 부분이라던지 막연하게 알고있던 스프레드 연산자에대해 좀 더 확실하게 알고 넘어가게 되는 계기가 될 수있어서 좋았고 컴포넌트를 어떻게 관리하고 깔끔한 코드를 위해서는 어떻게 해야하는게 좋을지 스스로 고민을 하게 되는 기간이 되었습니다.

이번일을 계기로 언제나 가지고있었던 예쁘고 깔끔한 코드를 만들자 라는 생각에 보다 다가갔으면 좋겠습니다

좋은 웹페이지 즐겨찾기