Minwook’s portfolio

PairZ 프로젝트 회고 본문

프로젝트

PairZ 프로젝트 회고

yiminwook 2023. 5. 2. 20:30

프로젝트 소개

pairz는 태블릿이나 pc와 같은 다양한 환경에서 url주소 하나만으로 카드게임을 즐길 수 있도록 개발된 프로젝트입니다.

사용자가 직접 이미지를 올려서 게임에 기여할 수 있습니다. 또한 게임을 진행 후에 사용자는 스코어를 기록할 수 있습니다.

 

핵심기술.

1. firebaseClient를 사용한 googleAuth 로그인

2. s3로 이미지를 업로드하고 이미지 주소를 fireStore에 저장

3. useCallback 과 useMemo를 사용하여 react rendering 최적화

 

Auth Flow

1. FirebaseClient로 AuthModal를 열고 사용자가 로그인

2. onAuthStateChanged firebase 내장함수로 유저정보를 state를 받는다.

3. recoil로 유저정보를 전역으로 관리

 

Game Flow

1. 게임에 시간제한을 둔다. useEffect로 state를 1씩 감소시키는 타이머를 구현 0이 될 시 게임오버.

2. Life는 3, pair를 잘못 맞추면 하나씩 감소된다. 0 일시 게임오버

3. Pause를 최대 3번까지 가능, Modal를 열고 닫을 때마다 state를 하나씩 감소시키고 0이 될 시 더 이상 pause 할 수 없다.

4. 서로 같은 색을 가진 5쌍의 카드를 생성, 각 카드는 고유한 index를 가진다, useMemo로 메모이제이션

5. 서버에서 랜덤으로 5장의 이미지를 가져온다. 이미지와 카드는 서로 index로 참조된다.

6. 피셔-예이츠 셔플로 순서를 무작위로 섞는다.

7. 일정한 시간동안 카드가 공개되고 다시 뒤집힌다, 뒤집는 효과는 className을 변경하여 scss로 구현

8. 첫번째로 고른 카드를 state로 기록하고, 두 번째로 고른 카드와 index를 비교

9. pair일시 두장 다 카드를 오픈하고 점수가 증가, no pair일시 두장 다 카드를 뒤집고 카드 state를 초기화, life를 1 감소

10. 10장을 카드를 제한 내 다 뒤집으면 round가 증가, 서버에서 랜덤으로 카드 5장을 요청, 메모이제이션한 카드를 셔플

 

 

 

Upload Flow

1. label을 Upload 버튼으로 사용, onDragEvent를 걸어서 Drag and Drop 구현

2. File type을 검증하고 png 또는 jpg라면 state로 받는다. 

3. preview를 보여주기 위하여 URL를 생성, 이전 URL은 revoke를 하여 메모리 누수방지

4. 이미지를 사용자가 크롭 하여 수정할 수 있도록, react-cropper 라이브러리 사용

5. 이미지의 타이틀이 s3 이미지 주소가 되기 때문에, 서버로 타이틀을 보내서 중복검사 

6. preview로 최종적으로 사용자가 카드 이미지와 타이틀을 확인하고 서버로 전송하여 업로드

 

 

느낀 점

이번 프로젝트는 부트캠프를 수료 후에 타입스크립트, scss, Next.JS 독학을 하여 프론트, 백, 데이터베이스까지 모든 과정을 혼자서 고민하고 극복하면서 만들어낸 프로젝트입니다.

 이번 프로젝트에서 개인적인 목표는 이미지 파일 전송, 저장, 처리에 대한 경험을 쌓고 React hook을 적절하게 사용하여 웹게임인 만큼 동적인 화면에서 불필요한 랜더링을 줄여 성능을 최대한 끌어올리는 것이었습니다. 프로젝트를 하면서 공식문서를 여러 번 반복해서 보고, 스택오버플로우, 구글링을 하면서 수많은 시행착오를 쌓아 올리며 만족할만한 수준으로 끌어올릴 수 있었습니다.

 

 

Firebase 

기존에는 로그인 어떤 식으로 설계해야 할지부터 고민이 많았는데 firebase에는 observer나 자체적으로 authorization token, session 쿠키를 생성해 주는 함수를 지원해 주었기 때문에 간단하게 보안이 검증된 로그인 세션을 만들 수 있어 편했고  mysql과 같은 관계형 데이터베이스가 아닌 nosql을 처음 사용해 보았는데 개발 중간에도 스키마 변경이 쉬워서 개발속도를 올릴 때에는 nosql를 쓰면 좋다는 말이 매우 와닿았습니다. firestore에서는 index를 지원해 주기 때문에 복합쿼리를 보낼 때 정렬하는 것도 손쉬웠습니다.  

 

Recoil

Redux을 공부한 후에 여러 전역상태 라이브러리에 관심이 생겼고 그중 Recoil에 흥미가 끌렸습니다. 특히 Recoil에 끌렸던 이유는 React만을 위한 전역상태관리 라이브러리라는 소개문 때문이었습니다. recoil은 useState훅과 비슷하게 사용할 수 있어서 처음에는 진입장벽이 낮다고 느꼈으나, selector라는 순수함수는 접하고 나서 어렵다고 느껴졌습니다. 공식문서를 찾아보고, 구글링을 해서 atom을 구독하여 atom 상태가 변화할때마다 실행된다는 개념자체는 이해했지만, 지금의 프로젝트에서 selector를 사용하여 frontend flow를 만들어내는 건 너무나 어려운 과제였습니다. 또한 앞으로 계속해서 해결해나가야 할 과제라고 생각합니다. 다음에 프로젝트를 한다면 redux로 다시 돌아가 차근차근 flow를 만들어보면서 전역상태라는 개념을 다시 익히고자 합니다.     

 

HTML

bootstrap이나 charkra-ui를 쓰지 않고 프로젝트를 진행하다 보니 div태그만 반복적으로 되어서 가독성이 떨어졌고, semantic tag의 필요성을 느꼈습니다. 또한 이번 프로젝트에서는 useRef를 최대한 사용하여 useState를 사용했을 때 발생되는 랜더링을 최대한 줄이고자 하였습니다. 따라서 DOM에 대한 지식이 필요했고 HTML의 대한 이해가 부족했음을 느꼈습니다. 이번에 새롭게 알게 된 것은 label 태그의 다양한 활용에 대해서 알게되었습니다. checkbox를 활성화 시켜 스타일의 변화를 주거나, input[file]의 버튼역할을 대신 할 수 있다는 것이었습니다. 이 지식으로 mobileNav를 자바스크립트가 아닌 HTML과 CSS만으로 구현을 해보거나 input file을 display:none;으로 가리고 label로 업로드 버튼을 만들어서 멋지게 스타일링을 할 수 있었습니다. 

 

AWS - S3

AWS 아이디를 만들고 버킷을 생성하는 과정부터 쉽지 않았습니다. 로그인할 때는 IAM계정, 루트계정라는 생소한 계정종류에 공부하거나 버킷계정에 세밀하게 설정하고 나니 유데미에 끊어놓은 AWS 라이센스 강의를 빨리 들어서 공부하고 정리해야겠다는 생각이 들었습니다. 개발 중에 이미지를 받아오고 올리면서 quota에 대한 관심이 많이 생겼습니다. AWS는 1년의 무료서비스 기간과 1년중 GET 20000건을 무료로 제공하는데 한달 개발중 GET만 500건이 넘게 사용되어 quota도 신경을 쓰면서 개발을 해야겠구나 하는 생각이 많이 들었습니다.   

 

 

개선할 점

위에 Recoil 느낀점에서도 언급했지만 유저정보를 firebase observer로 가져와서 Recoil로 전역으로 관리를 하고 있는데

새로고침을 했을 때 유저정보가 한번 undefined가 찍혀, 무조건적으로 upload페이지 로그인 검증을 할때 redirect가 되는 문제가 있었습니다. 때문에 해당 기능을 빼고 upload 할시 로그인 검증을 하는 방식으로 바꾸었습니다. 

최근 SWR이나 react-query를 공부하면서 세션 쿠키와 함께 서버에 GET요청을 보내고 캐시 하여 유저데이터를 받아오는 방식을 알게 되어 해당 방식으로 개선할 수도 있겠지만 Recoil를 사용한 만큼 좀 더 Recoil과 Redux에 대해 공부하여 전역상태를 잘 관리하여 해당 문제를 해결할 수 있도록 더 공부해 볼 생각입니다.

 이번에 css라이브러리 없이 scss로 모든 스타일링을 구현을 했는데 결과적으로 module scss를 사용하면서 그 장점을 잘 살리지 못했다고 생각합니다. className을 일일이 다 붙이지 말고 컴포넌트 단위로 나누고 css선택자를 써서 불필요한 className을 지워 jsx와 scss코드를 좀 더 깔끔하게 정리가 하려고 합니다.   => 개선완료

 

Comments