5월 12일부터 5월18일까지 진행했던 솔로프로젝트에서
새로 배운점과 내가 못했던 점들을 적어서 다음에 이런일이 있을 때
참고하기 위해서 적어본다.
구현 화면
먼저, 깃 브랜치 전략을 사용하여 기능별로 브랜치를 따서 작업을 하고 PR하는 식의 작업은 처음해보았다.
모르는 것 투성이라 당장 시작을 하지도 못하여 구글링을 통해 리액트 초기세팅을 한 브랜치를 따서
브랜치를 생성(git checkout -b 브랜치명) 하는방법부터 배워갔다.
그 브랜치에서 npx-create-react-app, react-router-dom , axios 등을 npm install하여
main 브랜치로 PR, merge까지 하여 main에 초기세팅을 해주었다.
그 다음 각 기능별로 브랜치를 따면서 코드를 치기 시작하였다.
사실 폴더구조를 나눌때도 엄청난 고생을 했다. 제대로 폴더구조를 이렇게 하겠다! 하고
확실하게 정해놓고 하지않아서 진행되면 진행될수록 점점 뼈저리게 느꼈다.
컴포넌트, 커스텀훅, 페이지 구조를 정확히 나누어서 했어야했는데
내가 짜고있는 파일에 코드가 어디있는지 계속 찾고있는게 완전 잘못된것 같다. 앞으론 폴더구조 확실하게하자
각 기능별 구현사항
헤더
git checkout -b Header 명령어로 먼저 Header라는 브랜치를 만들고
헤더부분은 특별히 문제되는건 없었다. 다만, 라우터를 줄 때 Link 문법이 자세히 생각이 나지않아
이 마저도 구글링으로 해결해야했다.. Link to 정도는 바로바로 쓸수있게 연습하자...
모달
모달은 portal을 이용하여 구현하였다. useOutSideClick이라는 커스텀훅을 만들었다.
이 커스텀훅은 모달을 제외한 외부 영역을 클릭했을 때를 감지하여서 callback함수를 실행할 수 있는 함수이다.
콜백함수는 onClose로 모달을 닫게 하는 함수를 실행시켜주는 것이다.
메인페이지
메인페이지는 axios로 서버로부터 데이터를 받아올때 params를 주어 4개만 받아와서
메인페이지의 상품리스트에 렌더링 해주었다.
북마크 리스트는 localStorage를 사용하여 브라우저에 저장을 해주었는데
상품마다 별마크를 클릭했을때 이벤트가 걸리는 함수를 작성하였다.
그 함수는 사용자가 어떤 상품의 별마크를 눌렀을 때 로컬스토리지에
이미 그 상품이 저장되어 있는지 findIndex 메서드를 통해 체크하고,
저장이 되어있다면 filter메서드를 통해 로컬스토리지에서 제거해준다.
저장이 되어있지 않다면 updatedBookmark배열의 맨앞에 추가해주었다.
상품리스트 페이지
상품리스트 페이지로 넘어가보면 전체 데이터들이 쭉 렌더링되고
상단에 타입별로 필터링해주는 컴포넌트가있다.
filter 컴포넌트는 전체, 상품, 카테고리, 기획전, 브랜드 별로 section을 만들어주고
그림이나 텍스트를 클릭하면 각 section에 있는 onClick이벤트를 통해
각 타입으로 바꿔주면서 setFilter 상태변경함수를 통해서 해당 타입의 데이터들만 렌더링해준다.
렌더링해주는 방법은 메인페이지에서 했던 방법과 똑같이 했다.
북마크리스트 페이지
북마크리스트 페이지 또한 메인페이지에서 4개 렌더링한 북마크리스트처럼
로컬스토리지에서 getItem메서드를 통해 가져온 데이터들을 토대로
filter 컴포넌트를 사용하여 상품리스트 페이지처럼 각 타입별로 렌더링해주었다.
구현 중 생긴 문제점
Git 사용법 미숙지
이번 프로젝트를 하면서 생긴 첫번째 문제는 git문제였다.
항상 해오던 clone, add, commit, push를 넘어서
checkout, pull, upstream 등등 자주 사용해보지 않은 명령어를 사용해야하다보니
중간에 파일이 날아가거나 의도하지 않게 동작이 되어서
push못하고 commit만 된상태로 먹혀버린다거나 이런 당황스러운 일이 일어나서
엄청나게 애먹었다. 아래의 블로그를 통해 각 명령어와 깃브랜치 전략에 대해 정확히 알고나니
하나씩 알아가서 막바지에는 고민하지않고 깃을 사용할 수 있게되었다.
역시 명령어를 무턱대고 사용하기 보다는 왜 사용하는지를 알고 사용해야 머리에 잘남는 것 같다.
Card컴포넌트 미제작
이 문제도 엄청난 파국을 만들어낸 실수였다.
메인페이지, 상품리스트 페이지, 북마크리스트 페이지
어느곳에서나 사용했던 데이터의 이미지, 이름, 설명을 담을 큰 컴포넌트를 만들지 않은 것이다.
즉, 렌더링이 중복되는
위와 같은 카드 리턴코드를 페이지들마다 계속 하나하나 주고있었던 것이다.
페이지마다 7~80줄을 더 쓰고있었던 것이다.
뒤늦게 모달을 만드는 중에 계속 모달이 렌더링된 다른 모든 데이터들이 겹쳐서 나오는 것이였다.
이유를 끝까지 모르던 와중에 동기분이 Card컴포넌트를 따로 만들지않아서 props가 꼬여서
모달이 띄워질때 렌더링된 모든 아이템들이 다 모달로 뜬다는 것이였다.
따라서 눈물을 머금고... Card컴포넌트를 만들기위한 리팩토링을 시작하였다.
만들땐 이리 헷갈리고 저리 헷갈려서 props를 자꾸 다른 컴포넌트로 내려주거나,
로직들을 손보느라 고생을 좀 했지만 딱 만들어놓고 나니까
와... 난 지금까지 이걸 왜 컴포넌트로 안나누고 했을까라는 생각이 바로 들었다.
코드를 434줄이나 줄일수 있게 되었다... 이걸 보고나서 컴포넌트 잘나누자.. 100번은 생각했다.
localStorage 사용법 미숙지
하... localStorage.. 진짜 이거로만 14시간은 태운거같습니다...
localStorage 개념이 이해가 죽어도 안되서 아무리 봐도봐도 이해가 안가서
로컬스토리지에 관한 블로그만 20개는 본 것 같다.
결국 해결했긴 했지만 localStorage 공포증도 같이 생긴 것 같다.
코드상으로는 상당히 간단했지만 머릿속으로 이해하고 쓰기에는
시간이 너무 오래 걸렸다.
원래 정상적인 작동으로는 북마크별을 클릭하면
해당하는 아이템의 정보들만 로컬스토리지에 담겨야하지만
계속 내가 이해한대로 코드를 작성해보면 localStorage에 저장되는 데이터는
렌더링되는 전체 데이터가 계속 저장되는 것이다.
위처럼 코드를 작성했어야했는데
9번~17번까지의 로직이 생각이 나지않아서 고생을 엄청했었다..
로컬스토리지에 포함된 객체는 빼주고, 없었던 객체는 넣어주는
이런 생각을 하지못해서 그냥 onClick으로 handleBookmark함수가 실행되면
로컬스토리지에 추가가되게 하려고 하다보니까
axios와 params를 통해 받아온 데이터 4개를 그대로 로컬스토리지에 담아버리게 되어서
계속 onClick 이벤트가 감지되었을 때 어떤 카드의 북마크별을 누르던지 4개가 통째로 들어가버린 것이였다.
즉, 과거의 잘못된 코드는 18번째 코드에서 JSON.stringify(itemList)을 주어서
axios로 받아온 4개의 데이터인 itemList가 그대로 계속 로컬스토리지에 들어갔던 것이다.
위처럼 바꾸어 주면 정상작동한다.
내가 이걸 진짜 완성할 수 있을까... 걱정도 많고 생각도 많았던 첫 all프로젝트
크루님들의 코드리뷰도 받아보고 현업에서도 무조건 사용하는 git 사용법도 익힐 수 있는 시간이였고
내가 아직 react 뿐만아니라 js문법도 엄~청 부족하구나 느꼈던 시간이였고
공부에는 끝이없다..!! 그냥 머리깨면서 부딪혀보자.
코드리뷰 영상까지 너무 정성스럽게 올려주신 크루님들, 다른 동기분들 정말 감사합니다.
코드리뷰 남겨주신 모든분들 정말 감사합니다 많이 배웠습니다!!