1차 프로젝트 회고 - simple

mia·2023년 1월 13일
3

🎀 SIMPLE

이번 프로젝트에서 나는 PM(Product Manager)를 맡았다.
원래 리더의 역할은 자주 맡았기 때문에 큰 걱정은 없었지만 처음으로 백엔드와의 통신을 해야한다는 점, 팀의 방향성을 잡아주어야한다는 점에서 부담이 컸다. (많은 분들의 걱정을 들어 더 마음이 쓰였을지도..?)
멘토분들과 방향성과 우리가 이번 프로젝트에서 얻어야 할 부분을 다시 체크하고 나 또한 마인드 세팅을 다시 했다.
나의 개인적인 이번 프로젝트의 목적은 소통 & 통신이었다.
우리에게는 2차 프로젝트와 기업협업이 남아있었고 1차 프로젝트에서는 우리의 위치? 현재의 실력에 대해 인정하고 무리하지 않는 것이 정신적으로 도움이 된다고 생각했기 때문이다.
결과적으로 성공적이었다.
팀원들의 실력 격차도 크게 나지 않았고 다들 미루지 않고 열심히 해준 덕에 진행 속도에 있어 리마인드 해줄 필요가 없었다.
다만 조금 아쉬운 부분이 있었다면 프론트와 백의 소통부분에서 충분히 소통했다고 생각했지만 세세한 부분까지는 신경쓰지 못해 나중에 수정해야하는 부분이 많았다.

준비과정



준비해야할 부분이 어떤 것이 있을지 생각해보았을 때 시간을 간단하게 체크할 수 있는 WBS와 백엔드와의 소통을 위한 요구사항 정의서가 있었다.
다만 트렐로의 사용으로 WBS를 잘 활용하지 못했고 요구사항 정의서 또한 자세하게 적어두지 않아서 처음 백엔드 데이터 테이블을 만들때에만 잠시 사용할 수 있던 것이 가장 큰 아쉬운 점이다.

⚙️ Tech

1. 메인페이지

a. 구현 목표

  • 데이터 베이스 상의 제품을 가져와(API 통신) 메인 페이지에 구현
  • 메인 상단 및 상품 이미지 캐러셀 구현(프레임 워크 사용 x)
  • 각 아이템 클릭시 상세페이지 이동 & 장바구니 버튼 클릭시 로그인되어있으면 장바구니에 아이템 추가, 되어있지 않으면 로그인페이지로 이동.

b. 구현 사항 설명

  • 제품 하나를 그려줄 수 있는 컴포넌트(product)생성.
  • 데이터 베이스의 제품을 map함수를 사용하여 페이지에 그려줄 수 있는 컴포넌트(products) 생성.
  • 하나의 컴포넌트(product)를 활용하여 두가지 카테고리("따끈따끈한 신상" & "지갑은 가볍게 양손은 무겁게")에 활용하기 위해 main 컴포넌트에서 통신 후 받은 정보를 products에 props로 넘겨준 뒤 map함수로 화면에 구현.
  • 각각의 제품 클릭시 제품의 id를 받아 detail/${id}로 이동.(router에서 detail의 path는 detail/:id로 변경)
  • cart 아이콘 선택시 item의 클릭 이벤트가 같이 전달되는 이벤트 버블링이 발생하기 때문에 e.stopPropagation()로 자식 요소에 이벤트가 전달되는 것을 막아줌.
  • cart 아이콘 클릭이벤트 발생 시 선택된 아이템에 id값과 name을 전달해주어 id 값으로는 장바구니에 추가될 수 있도록 body에 전달, name은 alert창에 뜰 수 있도록 전달.

  • 이벤트 페이지에 구현할 이미지를 한장씩 100vw로 가로길이 지정 후 flex를 적용시켜 가로 정렬.
  • 전체를 감싸는 div는 overflow: hidden으로 숨겨줌(이 div의 가로길이는 100vw)
  • setInterval로 2초마다 transform을 -100vw로 주어 자동으로 사진이 넘어가는 것처럼 보이게 설정.
  • 제품의 좌우 버튼을 이용한 carousel 구현은 data의 길이를 받아 길이가 정해진 화면에 보여지는 갯수를 넘길 경우 길이에서 하나 빼서(화면에 빈 화면은 빼고 보여주기 위해) 그 값에 카드의 길이를 곱한 값을 기준으로 보여주는 화면의 위치 변경

c. 성장 포인트

  • 각각의 변수를 받아야하는 부분을 컴포넌트 내에 만들어 두었다면 꼭 채워주어야한다.(혹시라도 체크해본다고 변수로 설정해둔 후 npm start를 누른다면 흰 화면만 보이게 된다.)
  • 클릭 이벤트에 event값과 함께 id, name 등 다른 정보를 함께 전달해주려면 onClick = {e => addCart(e, id, name)}의 형식으로 구현, 또는 e를 생략한 후 onClick = {() => addCart(id, name)}으로 전달 후 함수에서 event 전달 받는 매개변수를 사용하면 된다.
  • searchParams의 set 메서드는 같은 이름의 키만 변경하기 때문에 새로운 이름의 키를 추가할 때에는 set메서드 사용하기!
  • react-icons의 활용.
  • stylelint: 스타일에 규칙을 주어 협업할 때 하나의 standard로 스타일을 짤 수 있는 lint로 안에 팀별로 컨벤션을 정해 놓아야한다.(ex. camelCase, nesting depths 등등..)

2. 카테고리 & 아이템 리스트

a. 구현 목표

  • 상품 리스트는 메인페이지와 동일.
  • Nav바의 카테고리란에 마우스 호버 시 메뉴가 뜰 수 있도록 설정.
  • 카테고리 선택시 각 item-list로 이동하도록 설정.
  • 상품 리스트 상단의 select option 선택시 최신순, 가격 낮은 순, 가격 높은 순으로 상품을 보여 줄 수 있도록 설정.
  • 스크롤 버튼 클릭 시 최상단으로 이동.

b. 구현 사항 설명

  • categoryWrapLeft div안에 category 컴포넌트 추가(wrap -> position relative, category-> position absolute) => 화면 사이즈가 변경되더라도 카테고리 하단에 카테고리 정보가 뜰 수 있도록 함.

  • categoryWrapLeft의 mouseEnter 이벤트 발생 시 isMouseHover state는 true.

  • category에 mouseLeave 이벤트 발생 시 isMouseHover state는 false. => hoverCategory 함수에 boolean 값을 주면 하나의 함수로 두가지 동작(true, false)를 실행할 수 있다.

  • isMouseHover state가 false일 때 category의 class는 hidden으로 변경되어 보이지 않게 됨.

  • searchParams.set을 통해 click event 발생시 id 값을 받아 url에 category=id의 형태로 바꿔줌.

  • searchParams.get을 통해 url의 값을 받아와 useNavigate를 통해 이동시켜줌.

  • itemList -> selectList의 각각의 옵션에 value값을 주어 selectList에 change event발생시 searchParmas의 sort값에 value값을 적용시켜주어 url 변경.

  • Nav에서 받은 category와 itemList의 sort값(쿼리스트링)으로 백엔드와의 통신을 하여 그에 맞는 제품을 보여줌.


  • 스크롤 버튼 -> window.addEventListener('scroll')을 통해 scroll event 감지.

  • Y축 200이상일 경우 버튼 생길 수 있도록 구현.

c. 성장 포인트

  • mouseOver vs mouseEnter -> mouseOver는 자식 요소에 발생한 이벤트가 적용되지 않으며 mouseEnter는 자식요소에도 이벤트가 전달된다. (카테고리 컴포넌트도 mouseEnter 이벤트 발생 시 사라지면 안되기 때문에 mouseEnter 사용)
  • mouseLeave -> 해당 이벤트가 category component가 아닌 categoryWrapLeft 안에 있다면 category에 호버했을 때는 카테고리가 사라지게 될 것이다. 따라서 category component(자식 요소)에 mouseLeave를 넣어주었다.
  • map함수 사용시 각각 다른 react-icons를 넣어주려면 변수자체에 <>를 포함시켜주면 잘 작동된다.

3. 검색창

a. 구현 목표

  • searchParams를 이용한 검색창 기능 구현

b. 구현 사항 설명

  • searchParmas.set을 통해 nav에서 입력된 inputValue를 search key에 저장 -> setSearchParams를 통해 url에 띄워줌.
  • searchParams.get을 통해 검색결과를 띄워줌.

c. 성장 포인트

  • searchParams에 대한 확실한 이해 완료.
  • searchParams의 호출은 구조분해할당과 같다. 따라서 setSearchParams가 필요없다면 적지 않아도 된다.

✍️ 개인적인 회고..?

주어진 과제는 클론 코딩이었지만 팀원들과의 상의를 통해 기본적인 레이아웃만 참고한 후 우리의 색을 녹여내기위한 노력을 많이 했다.
다만 백엔드와의 통신은 처음이었기 때문에 mock-data로 구현한 내용을 직접 통신하는 부분으로 바꿀 때에 많은 변경사항이 생기며 많은 conflict를 만날 수 있었다.
단순한 부분도 서로 많은 이야기를 나누어야 나중에 충돌이 생기지 않는다는 것을 알게되었다.
소통이 정말정말 중요하다는 것을 깨닫는 계기가 되었다.

profile
노 포기 킾고잉

1개의 댓글

comment-user-thumbnail
2023년 1월 14일

mia 님 발표 어떻게 하셨는지도 적어주세요!!! 😍 진행방식이 참신하면서도 내용은 알찬 최고의 프레젠테이션이었어요 👍👍 꼭 써주세요 꼭이요!!! ❤️‍🔥❤️‍🔥❤️‍🔥❤️‍🔥❤️‍🔥❤️‍🔥

답글 달기