소개
맛집에 대한 경험 기록 및 공유를 통해 차원이 다른 맛집 순례 라이프를 즐길 수 있도록 도와주는 나만의 맛집 지도 & 일기
- 맛피플들의 다양한 후기가 담긴 맛포스트를 통해 증명된 맛집 후기를 얻어 더욱 퀄리티 높은 맛집 탐방 즐기기
- 방문하고 싶거나 재방문하고 싶은 맛집을 골라 맛픽커 그룹에 저장하여 맛집 지도 만들기
- 맛집을 방문한 후 해당 맛집에 대한 나의 경험과 후기가 담긴 맛포스트를 작성하여 추억이 담긴 맛집 일기장 만들기
- 기간: 1월 4일 ~ 2월 1일 (약 28일)
- 깃허브: http://bit.ly/3YWi3ZI
- 배포 링크: http://bit.ly/3YBZTg7
기술 스택
- Typescript, React, Axios, Mui, Styled-Components, Eslint
담당 기능
- 맛포스트 모달 디자인 및 기능 구현
- 서버 통신 로직 분리 및 실시간 데이터 업데이트 로직 구현
- 맛피플 페이지 및 맛피플 검색 페이지 디자인 및 기능 구현
- 도메인 페이지 디자인(Grid UI) 및 기능 구현
- 별점 통계 차트 및 별점 매기기 기능 구현
회고
1. 맛포스트 CRUD
- Modal
맛포스트를 조회, 작성 및 수정 Modal을 구현하여 유저가 맛플레이스에 대한 후기를 남기며 추억 및 후기를 기록할 수 있을 뿐 아니라, 다른 맛피플의 맛포스트 조회 후 댓글 작성을 작성하거나 ‘좋아요’를 누를 수 있도록 하였습니다. 해당 기능을 통해 후기지향적인 애플리케이션의 컨셉에 따라 유저간의 소통 및 정보 공유가 활성화 되며 유저가 다양한 맛집의 정보를 접할 수 있도록 하였습니다.
어려웠던 점 ⁉️
처음 Modal을 만들 때 z-index와 Position의 개념 이해 부족으로 인해 원하는 곳에 Modal을 배치하고 Modal 창이 떠있는 동안 다른 컴포넌트에 Backdrop을 적용시키는 데에 어려움을 겪었습니다.
Header와 Sidebar 컴포넌트가 Modal의 부모 요소가 되다보니, 아무리 Modal의 z-index를 높게 설정 해주어도 Backdrop이 적용되지 않았습니다. 해당 문제는 Modal Portal을 적용하는 방식으로 해결하였습니다.
- React-quill(Text Editor)
유저가 맛포스트 작성 시 이미지를 첨부할 수 있도록 Text Editor 라이브러리인 React-quill을 사용하였습니다.
react-quill 라이브러리에는 이미지 사이즈 조절 기능이 구현되어 있지 않아, 추가적으로 이미지 resizing 라이브러리를 이용하여 유저가 Post를 작성하며 이미지의 사이즈를 조절 할 수 있도록 하였습니다. 또한 이미지 업로드 핸들링 함수를 구현하여 에디터 내에 이미지가 삽입될 경우 서버에 이미지 저장 및 url 변환 요청을 보내 에디터 내 이미지가 업로드 된 커서 위치에 src 값이 해당 이미지의 url인 img 태그가 삽입되도록 하였습니다.
어려웠던 점 ⁉️
타입스크립트가 적용되는 텍스트 라이브러리 중 파일 업로더를 통해 이미지를 업로드 할 수 있는 기능을 가진 라이브러리를 찾기가 쉽지 않았습니다. 또한, 제가 직접 만든 컴포넌트가 아니다보니 CSS를 적용하는 데에 큰 어려움을 겪었습니다. 처음 라이브러리를 설치하고 텍스트 에디터를 실행 하였을 때, 툴바에 있는 ‘bold’ 및 ‘italic’ 기능이 정상 작동되지 않아 적잖이 당황을 하였습니다. 해당 기능은 텍스트 에디터를 사용하는 컴포넌트에서 직접 설정해주는 방식으로 해결하였습니다.
두번째 어려움은 맛포스트의 썸네일 url을 추출해주는 부분이였습니다. 유저가 포스트 작성 시 등록한 첫 번째 이미지의 url 을 해당 포스트의 썸네일 url로 지정하여 도메인 페이지에 해당 썸네일 이미지가 표시 될 수 있도록 해야하였습니다. 해당 문제는 유저가 작성한 Post Content에서 img 태그를 찾아 유저가 등록한 첫 번째 이미지의 url을 추출하는 로직을 작성하여 구현에 성공하였습니다.
- Mui Popover
맛포스트 또는 댓글 삭제 시 유저가 실수로 삭제 버튼을 눌러 원치않는 삭제가 이루어질 경우를 고려하여, Mui Popover 라이브러리를 사용하여 삭제 요청을 재확인하여 처리하는 기능을 구현하였습니다.
어려웠던 점 ⁉️
Popover 또한 타입스크립트가 적용되는 라이브러리를 찾기가 쉽지 않았습니다. 타입스크립트가 적용되는 라이브러리를 찾고 난 후에도 Popover나 Tooltip을 사용하여 Delete Confirm 기능을 만들어본 경험이 없는 탓에 해당 컴포넌트의 배치를 하는데에 있어서도 애를 먹었습니다. ‘삭제’ 버튼 클릭시 버튼의 하단에 띄워보려고 하였으나, Modal에 가려져 보이지 않는 현상이 있었기 때문입니다. 해당 문제는 Popover의 z-index 값을 Modal 보다 높게 설정하는 방법으로 해결하였습니다.
아쉬웠던 점😮💨
Yes / No 버튼이 텍스트의 아래에 위치하도록 만들고 싶었지만, Popover style 적용에 대한 미숙함과 시간 부족으로 결국 구현하지 못한게 된 것이 아쉽습니다.
2. 네트워크 통신 코드 추상화한 useAxios 커스텀 훅 & 네트워크 통신 API 문서화를 통한 데이터 리로딩 기능
코드 가독성 및 재 사용성을 높이기 위해 네트워크 통신 후 response를 받아오는 useAxios 커스텀 훅 구현 및 네트워크 통신 관련 코드 도메인 별 API 문서화 과정을 진행하였습니다.
callback 함수에는 원하는 네트워크 통신 관련 메소드(GET, POST, PATCH, DELETE 요청)를 넣어줍니다.
deps는 종속성 배열로, axiosData 함수가 실행될 조건들을 넣어줍니다.
skip이 false이면 컴포넌트가 렌더링 되자마자 실행되고 true이면 컴포넌트가 렌더링이 되어도 바로 실행되지 않습니다. skip을 true로 설정할 경우, 컴포넌트 렌더링 이후 POST나 PATCH 요청으로 인한 데이터의 변동이 발생한 이후에 변경된 데이터를 받아올 수 있도록 하여 맛포스트 등록 및 댓글 수정 이후에도 동일하게 작동될 수 있도록 하였습니다.
이를 사용하여 데이터에 변동이 있을 경우, 컴포넌트가 리렌더링 되며 데이터가 실시간으로 업데이트 되도록 구현하였습니다.
1. 컴포넌트 내에서 boolean 값을 가지는 state를 만들고, 해당 state 값을 바꾸는 함수를 생성합니다.
2. 데이터의 변경을 핸들링하는 로직에 이 함수를 추가하여, 데이터가 변경 될 시 state의 값이 바뀌도록 만들어줍니다.
3. useAxios의 종속성 배열에 1에서 선언한 상태 값을 넣어 상태값 변경 시 axiosData 함수가 실행되어, callback 함수인 네트워크 통신 함수가 실행되며 response data가 바뀌어 실시간으로 업데이트 된 데이터를 볼 수 있도록 합니다.
해당 로직을 이용해 맛포스트 모달 내 댓글, 도메인 페이지의 ‘좋아요’ 및 맛피플페이지의 유저 팔로우/언팔로우 기능에 대한 실시간 업데이트 기능을 구현하였습니다.
어려웠던 점 ⁉️
useAxios 커스텀 훅을 사용하기 전에는 모든 처리가 종료된 후 다시 한번 GET 요청을 보내 업데이트 된 데이터를 가져오거나 useEffect 내에서 GET 요청을 보내 컴포넌트가 리렌더링 되도록 하는 등의 방식을 사용하였기에 데이터 실시간 업데이트는 저에게 있어서 가장 걱정되고 어렵게 다가온 부분 이였습니다.
’추상화’ 라는 개념이 익숙하지 않아 useAxios 커스텀 훅에 대한 로직이 피부에 한번에 와 닿지 않았고, 이를 이해하고 적용하는 데에 어려움이 있었지만 useAsync 등과 같은 커스텀 훅에 대한 예시를 많이 찾아보고 적용 방식을 이해하며 프로젝트에 적용시키기 위해 노력하였습니다.
3. Star Rating
후기 지향적인 애플리케이션의 목표에 맞춰 맛플레이스 상세 페이지에 포함되는 각 맛플레이스 별 Star Rating 및 Star Rating Chart 컴포넌트를 구현하여, 유저가 한눈에 해당 맛플레이스에 대한 맛피플로 부터 보장된 후기를 얻을 수 있도록 하였습니다.
마치며
이번 프로젝트는 팀원 모두에게 새로운 도전 이였다고 생각합니다. Typescript, Recoil 등 새로운 기술 스택 학습과 프로젝트 진행을 병행하는 것이 쉽지는 않았지만, 프론트엔드 팀원분들과 함께 자료를 나누고 공유해가며 학습하여 다함께 성장하는 뜻깊은 경험을 할 수 있었습니다. 짧은 시간 내에 새로운 스택을 배우고 프로젝트에 적용해보는 경험을 통해 새로운 것에 대한 거부감을 없애고 새로운 기술에 대한 흥미와 학구열을 상승시킬 수 있던 기회가 아니였나 생각됩니다.
또한 매일 아침 9시 스크럼 회의를 통해 진행 및 애로 사항을 나누고 기록하며, 팀원 들과 적극적으로 소통하여 협업 및 커뮤니케이션 능력을 기를 수 있었습니다.
아쉬웠던 점😮💨
다만 시간적 여유 부족으로 디자인적인 면에 신경을 많이 쓰지 못했던 것과, 뒤 늦은 상태관리 라이브러리 도입으로 인한 약간의 props drilling 을 쓸 수 밖에 없었던 상황이 아쉽게 느껴집니다.
이에 따라 프로젝트 종료 이후 Typescript 및 상태관리 라이브러리(Recoil 등)에 대한 추가적인 학습을 진행 해야겠다는 생각이 들었습니다.
'코드스테이츠 SEB FE 41기 > Main-Project(MatP)' 카테고리의 다른 글
[react] 반응형 모달 만들기 (0) | 2023.02.02 |
---|---|
[react & typescript]리코일 찍먹(?) 사용기 - 로그인한 유저 정보 저장하여 전역 상태로 관리하기(feat. recoil) (0) | 2023.02.02 |
[react] 프로필 이미지 변경하기(feat. typescript) (0) | 2023.01.31 |
[react & typescript] useAxios 커스텀 훅 사용기2 - 데이터 실시간 업데이트해보기 (0) | 2023.01.31 |
[react & typescript] MUI Popover 사용기(Delete confirm 기능) (0) | 2023.01.31 |