yoyoujin / nonamarket

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

1인 가구를 위한 공유 냉장고 노나먹자 🍴


image

목차

1. 프로젝트 소개

🔸  프로젝트는 1인가구에서 남는 식재료 또는 반찬을 공유할  있는 SNS 커뮤니티 입니다.

🔸 서비스 사용자들은 포스팅 기능을 통해 사진과 글을 기록하며 1 가구에 도움이되는 정보를 공유할  있습니다. 

🔸 무료로 나눔하고 싶거나 판매하고 싶은 물건이 있다면 상품 판매를 등록하고 본인의 SNS에 바로 홍보할  있습니다. 

2. 요구사항

🔐 인증

  • 로그인 / 로그아웃
  • 회원가입
  • 회원 정보 수정
  • 유효성 검증

🏕️ 게시글

  • 게시글 등록/수정/삭제/신고
  • 다중 이미지 파일 업로드/수정/미리보기
  • 앨범뷰 / 리스트뷰
  • 이미지 슬라이드
  • 좋아요 기능

👥 팔로우

  • 유저 팔로우/언팔로우
  • 팔로잉, 팔로워 리스트

🥗 상품

  • 상품 등록/수정/삭제
  • 이미지 파일 업로드/수정/미리보기
  • 유효성 평가

🔎 검색

  • 유저 검색
  • 무한 스크롤

💬 댓글

  • 댓글 등록, 삭제, 신고
  • 댓글 작성 시간

3. 팀원 소개

양지성 방현영 선은혜 한유진
🔗GitHub 🔗GitHub 🔗GitHub
🔗blog
🔗GitHub
총괄 팀장 코드 리뷰 리더 회의록 리더 디자인 리더

4. 역할 분담

nona-role



🛠 공통 담당

  • 공통 작업 : 로그인 / 회원가입 / 프로필 등록 / 버튼 컴포넌트

5. 개발 환경

1) 개발기간 : 2022.12.09 ~ 2023.01.05

2) 기술

  • FrontEnd : React, React-router, Hooks, Styled-components (수정하기)
  • BackEnd : 제공된 API 사용

3) 협업 도구

4) 이슈 관리

image

5) Git Flow

깃 브랜치 전략으로 GitFlow를 선택하였습니다. 큰 규모의 프로젝트에서 주로 사용되는 전략이지만, 기능 단위로 브랜치를 만들어 팀원간의 원활한 작업과 conflict를 최소화하기위해 경험삼아 도입하게되었습니다. 이 프로젝트에서는 규모에 맞게 3개의 브랜치를 사용하였으며 프로젝트기간동안 거의 confilct가 발생하지 않은, 기분좋은 경험을 할 수 있었습니다.

  • main : 정식 배포된 버젼을 담고 있는 브랜치
  • develop : 현재 개발이 완료된 상태와 일치하는 브랜치
  • feature : 기능 개발을 위한 브랜치로, 기능 구현이 완료되면 삭제되는 브랜치

6. UI

0. Splash 1. 로그인
2. 회원가입 3. 회원가입 - 프로필 설정
4. 홈피드 5. 검색
6. 게시글 등록 7. 게시글 수정
8. 게시글 삭제 9. 게시글 신고
10. 게시글 댓글 등록 및 삭제 11. 게시글 댓글 신고
12. 내 프로필 13. 내 프로필 수정
14. 타 유저 프로필 15. 팔로우
16. 판매 상품 등록 17. 판매 상품 수정 및 삭제
18. 로그아웃 19. 좋아요
20. 404 페이지 21. 채팅

7. 핵심 코드

1) useContext

  • token, accountname이 여러 컴포넌트 내에서 api통신을 할 때 필요로 하는 것을 발견.
  • 전역에서 필요한 token, accountname을 useContext를 이용하여 관리
  • useContext를 사용함으로써 prop drilling을 방지
  • token, accountname을 얻기 위한 불필요한 데이터 요청 방지

2) CustomHook

  • 모달 구현 시 모달이 필요한 여러 컴포넌트 내에서 동일한 로직이 반복적으로 사용되는 것을 발견.
  • 이를, useModal 이라는 커스텀 훅으로 만듦으로써 코드의 중복 최소화 및 상태 관리 로직의 재사용성을 높임.

3) Button 컴포넌트

  • 재사용성이 높은 버튼을 공통 컴포넌트로 만들어 여러 페이지 내에서 사용할 수 있게 구현함
  • 기본 버튼 컴포넌트 구현 후 버튼의 스타일 컴포넌트에서 사이즈,disabled,색상 등을 prop 인자로 받아와서 여러 페이지에서 사용할 수 있게 구현함.
  • 특히, 버튼의 사이즈를 SIZES 라는 객체(s,ms,m)로 변수를 지정하여 확장성있는 코드로 구현함

8. 트러블 슈팅

1) 양지성👨

[문제 상황]

  • 팀 프로젝트를 위한 github organizition 공용 repo를 생성하고 초기 세팅하면서 발생한 충돌(error)
  • 작업자 4명이 모두 같은 branch(당시 브랜치 위치: develop)에서 파일 편집 공동작업을 진행.
  • 작업자1이 push 후, 작업자2 가 push 를 시도하니 충돌 발생.
  • 작업자2의 로컬저장소와 공동repo인 원격저장소와 싱크가 맞지 않아 발생한 문제.
  • 작업자3,4도 git add. 까지 모두 마친상황. (각자의 로컬 저장소에서 변경된 파일의 상태를 스테이징 상태로 넘긴 상황)

[해결 과정]

  • 마주한 에러1 : failed to push some refs to ‘원격 repository주소’
  • 원격 저장소에 있는 파일이 로컬 저장소에는 없기 때문에 나타나는 error이다.
  • 원격 저장소와 로컬저장소의 싱크를 맞출 수 있도록 git pull 'origin develop' 명령어를 입력 후 다시 변경된 내용을 원격저장소로 push 해주어야 한다.

  • 마주한 에러2 : Your local changes to the follwoing files would be overwritten by merge: ‘파일명’
  • please commit your changes or stash them before you merge 안내 문구에 따라 스테이싱 되어있던 상태를 잠시 임시 저장소로 옮겨두고, 로컬 저장소에 원격 저장소의 가장최근상태의 branch를 로컬저장소로 merge 될 수 있도록 해주면 된다.

2) 방현영👧

[문제 상황]

  • 폰트 파일(Spoqa Han SanS Neo)을 다운로드 받아서 프로젝트 폴더 안에 저장하여 사용하고 있었으나 적용되지 않는 문제를 발견하게 되었다.
  • 개발자도구에서 렌더링된 글꼴이 Spoqa Han Sans Neo가 아닌 맑은 고딕이 적용되고 있었다.

[해결 과정]

  • 기존에는 폰트 파일의 경로를 url의 인자로 직접적으로 불러 왔었다. 그러나 리액트에서는 경로를 인자로 직접쓸 경우 리액트 실행시 경로가 바뀌어버리게 된다. 따라서, 파일(이미지, 폰트)를 가져올 때는 각 파일이 사용되는 부분에 바로 경로를 적는 것이 아니라 따로 import를 해서 가져와야 한다.

  • 경로를 import해서 가져왔음에도 불구하고 폰트가 적용되지 않았다. 혹시 Spoqa Han SanS Neo가 아닌 다른 폰트는 적용이 되는지 확인해보았는데 적용이 잘 되었다. 파일에 문제가 있음을 의심하고, 폰트 파일을 다시 다운 받았더니 Spoqa Han SanS Neo가 잘 적용 되었다.

  • 그러나 폰트가 어떤 태그에는 적용이 되고, 어떤 태그는 잘 적용이 되는 문제가 있었다. 이는 CSS 우선순위 문제였다. 기존에는 font-family를 * (전체 선택자)에 작성하였는데 reset css에 적힌 font:inherit은 태그 선택자에 작성되어있어 가중치 점수가 더 높기 때문에 전체 선택자에 작성한 font-family가 무시되는 것이었다. 따라서, reset css에 포함되지 않은 태그들(button)만 폰트가 적용이 되고, 나머지는 적용이 안되는 것이었다.

  • 그래서 전체 선택자가 아닌 body 태그에 font-family을 주었고, reset css에 font-inherit이 적힌 부분과 가중치 점수가 동일하기 때문에 후자 우선의 원칙으로 뒤에 작성된 body의 font-family가 적용이 되고, body에 포함된 태그들이 이를 상속받을 수 있게 되었다.

3) 선은혜👩‍🦰

[문제 상황]

  • 상품 삭제/수정/웹사이트 보기 모달창 구현시 가장 상위의 부모 태그(모달창 밖 검정색 배경화면) 에 onClick 이벤트를 주어 부모 태그를 클릭할 시에만 모달창이 닫히도록 구현할 계획이었다. 하지만, 자식 태그까지 onClick 이벤트가 적용되어 자식태그(모달창)를 클릭해도 모달창이 닫히는 이벤트 버블링 이슈가 발생했다.

[해결 과정]

  • 초반에는 자식 태그가 3개(삭제/수정/웹사이트에서 상품보기) 가 있었기에 각각의 자식 엘리먼트에서 e.stopPropagation을 활용하여 버블링 전파를 막았었다. 하지만, 코드가 중복되는 문제가 있었고, 한번에 처리할 수 있는 부모 엘리먼트 단에서 if (e.target !== e.currentTarget) return; 을 써서 해결 할 수 있었다.

4) 한유진👩

[문제 상황]

  • 게시글에서 작성페이지에서 중요한 기능인 이미지 미리보기 기능을 구현하는 중 어려움이 있었다. input 태그를 사용하여 유저가 파일을 선택할 수 있게 하였다. 이 때 파일을 선택하면 FileList 객체로 정보가 들어오게된다. 하지만 파일 선택 후 열기를 누르면 정작 화면에는 나타나지 않는 문제를 만나버리게된다.

[해결 과정]

  • FileReader 객체를 이용하여 file 읽기 : 보안상의 이유로 이미지의 상대경로가 블러처리되기때문에 발생한 문제였으며, Web API 중 FileReader라는 객체를 사용하여 미리보기 구현에 성공하였다. FileReader객체는 유저가 선택한 이미지를 File객체에 할당해 내용을 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 해준다. (이미지 외에도 비디오, 오디오, csv 파일 등 가능) File객체에 담긴 이미지 파일 값들을 FileReader의 메서드(readAsDataURL)를 이용하여 base64로 인코딩 해준다. 인코딩이 완료되면 문자열로 변환되며 이 문자열을 배열에 담아주고 map()을 사용해서 이미지태그를 여러개 만들어주는 방법으로 미리보기에 성공하게되었다.

9. 폴더 구조

📦src
 ┣ 📂api
 ┣ 📂assets
 ┃ ┣ 📂font
 ┃ ┗ 📂images
 ┣ 📂components    
 ┃ ┣ 📂Comment
 ┃ ┣ 📂CommentInput
 ┃ ┣ 📂common           // 공통으로 사용되는 컴포넌트 폴더
 ┃ ┃ ┣ 📂Button
 ┃ ┃ ┣ 📂ImageInput
 ┃ ┃ ┣ 📂LabelInput
 ┃ ┃ ┣ 📂Modals
 ┃ ┃ ┣ 📂PostAlbum
 ┃ ┃ ┣ 📂PostCard
 ┃ ┃ ┣ 📂Product
 ┃ ┃ ┣ 📂ProfileImg
 ┃ ┃ ┗ 📂TabMenu
 ┃ ┣ 📂ImagePreview
 ┃ ┣ 📂Loading
 ┃ ┣ 📂MenuBar
 ┃ ┣ 📂Nav
 ┃ ┣ 📂ProfileInfo
 ┃ ┗ 📂UserListItem
 ┃ ┃ ┗ 📂UserFollow
 ┣ 📂context         // 로그인 한 사용자 정보를 담기 위한 context 파일 관리 폴더
 ┣ 📂hooks
 ┣ 📂pages
 ┃ ┣ 📂AddProduct
 ┃ ┣ 📂ChatList
 ┃ ┣ 📂ChatRoom
 ┃ ┣ 📂EditPost
 ┃ ┣ 📂Follow
 ┃ ┣ 📂HomeFeed
 ┃ ┣ 📂JoinEmail
 ┃ ┣ 📂JoinProfileEdit
 ┃ ┣ 📂Login
 ┃ ┣ 📂LoginEmail
 ┃ ┣ 📂ModifyProfile
 ┃ ┣ 📂NotFound
 ┃ ┣ 📂PostDetail
 ┃ ┣ 📂Profile
 ┃ ┃ ┗ 📂UserProfile
 ┃ ┣ 📂SearchUser
 ┃ ┣ 📂Splash
 ┃ ┣ 📂UpdateProduct
 ┃ ┗ 📂UploadPost
 ┣ 📂Router
 ┣ 📂styles
 ┣ 📜App.jsx
 ┣ 📜index.css
 ┗ 📜index.jsx

10. 프로젝트 소감

👨 양지성

  • 코딩은 물론 프로젝트 개발환경 세팅, 기획논의 등등..어느하나 쉬운 것 없는 프로젝트였지만, 그 만큼 많이 성장할 수 있는 경험이였습니다. 불과 한달전에는 코드하나 칠때마다 쩔쩔 매고, 내가 가능할까 의심했었는데 지금은 그 순간도 미화된 추억처럼 ‘그랬었지..’ 할 정도로 시간이 빨리 지나갔고 성장 했음을 느낍니다. 본 프로젝트에서 많은 기능을 시도해보지는 못했지만 프로젝트를 완주했다는 만족감에 자신감도 얻어갈 수 있어 정말 좋았습니다. 마지막으로 팀장으로서 많이 모자란 저에게 팀장 대우 해주고 응원해준 25조 팀원들 덕분에 팀원들과 현생에서 conflict 없이 마무리 할 수 있었던 것 같습니다. 감사합니다.

👩‍🦰 선은혜

  • 팀프로젝트 하기 전 컴포넌트 조차 만들지 못했습니다.하지만, 이 팀프로젝트를 통해 API 명세를 해석하며 서버와 통신을 할수 있게 되었습니다. 특히, 다른사람의 코드를 한줄 도 이해하지 못했던 제가 이해가 잘 돼서 유레카! 외치던 그 순간을 아직도 잊지 못합니다. 그간 배워본 것을 실제로 프로젝트에 적용을 하니 코딩에 대한 흥미가 높아졌고, 무지성 클론코딩을 하던 습관에서 원리를 이해하고 활용할 수 있게 되었습니다~!! 👍
  • 첫 협업 프로젝트 였지만, 팀원들 모두 너나 할 것 없이 자진해서 자신이 맡은 부분을 최선을 다해 하고자 했기에 팀원 간의 불화 없이 잘 마무리 할 수 있었다고 생각합니다. 더불어, 부트캠프에서 기본적으로 제공되는 협업 툴이 아닌 우리만의 Notion/Discord채널에서 바로바로 소통을 했기에 사소한 오해 조차 없이 순탄하게 진행될 수 있었던 것 같습니다. 🙇‍♀️🙇‍♂️🙇

👩 한유진

  • 서버에서 데이터를 받아오고 보내는 작업을 처음으로 해보았는데 이 과정속에서 실제로 에러를 직면하고 콘솔로 찍어보면서 에러를 해결하는 과정이 짜릿했습니다😊 프로젝트 이전에는 코드에 대한 이해나, 두려움이 있었다면 지금은 두려움보다는 흥미가 더 커진 것 같습니다 ! 첫 협업 프로젝트라 부족한점이 많았지만 팀원들과 고민을 나누고 함께 해결하는 과정이 즐겁고 고마웠습니다. 팀원들이 아니었다면 이 프로젝트를 무사히 완주하지 못했을 것 같아요 ! ❤️
  • 팀원들과 개발환경을 맞추기 위해 프로젝트 초기에 eslint와 prettier 세팅을 진행하였는데 초반에는 린트에서 잡아주는 오류들이 많아서 약간의 피로감이 있었습니다. 그렇지만 어떤 부분이 잘못되었는지 알려주기 때문에 문제를 빠르게 해결할 수 있었고 불필요한 코드를 줄이게 되면서 코드의 질이 좋아졌다는 생각이 들었습니다.

👧 방현영

  • 프로젝트 시작할 당시에는 모든 것이 낯설었던 것 같습니다. 리액트를 공부한 이후로 만들게된 첫 협업 프로젝트이기도 했고 깃에 대한 경험도 부족했기 때문에 이런 저런 생각이나 걱정도 많았습니다. 하지만 걱정했던 것과는 달리 직접 부딪혀보니 어느순간 개발에 재미를 느끼고 있는 제 모습을 발견할 수 있었습니다. 로직을 짜고, 머리를 맞대고 같이 에러를 해결하기도 하고, 서로의 코드를 리뷰하는 그런 과정 속에서 때로는 지치도 하고 때로는 벅차오르는 순간도 있었습니다. 이런 순간 순간들이 모여서 리액트, 깃 뿐만 아니라 협업에 대한 자신감을 얻을 수 있었고, 개발에 재미도 느끼며 조금은 성장하는 계기가 되었던 것 같습니다. 무사히 프로젝트를 마무리하게 되어 뿌듯하고, 각자의 자리에서 최선을 다해준 팀원들에게 감사하다고 전하고 싶습니다! 💗

About


Languages

Language:JavaScript 98.1%Language:HTML 1.2%Language:CSS 0.7%