Solo - Coz Shopping

Coz-Shopping

개요

React를 사용해 주어진 요구사항을 만족하는 상품리스트 페이지와 사용자가 북마크 한 상품들을 조회할 수 있는 북마크 페이지를 포함하는 SPA 앱을 구현한다.

 

프로젝트 요구사항

 

사용스택

react

axios

redux toolkit

react-router-dom

react-toastify

styled-components

 

제작기간

5/12(金) : 프로젝트 요구사항 분석 및 플래닝

5/15(月) - 5/21(日) (7일간) : 프로젝트 구현

 

src 디렉토리 구조

📦src
 ┣ 📂Pages
 ┃ ┣ 📜Bookmark.js
 ┃ ┣ 📜Main.js
 ┃ ┗ 📜ProductList.js
 ┣ 📂components
 ┃ ┣ 📜Footer.js
 ┃ ┣ 📜HambergerModal.js
 ┃ ┣ 📜Header.js
 ┃ ┣ 📜ImageModal.js
 ┃ ┣ 📜ItemCard.js
 ┃ ┣ 📜MainBookmarks.js
 ┃ ┣ 📜MainProducts.js
 ┃ ┗ 📜Router.js
 ┣ 📂img
 ┃ ┣ 📜Codestateslogo.js
 ┃ ┣ 📜CozShopping.js
 ┃ ┣ 📜Gift.js
 ┃ ┣ 📜Hamberger.js
 ┃ ┣ 📜HeaderStarIcon.js
 ┃ ┣ 📜StarIcon.js
 ┃ ┣ 📜StarIcon_Gray.js
 ┃ ┣ 📜XIcon.js
 ┃ ┣ 📜all.png
 ┃ ┣ 📜brand.png
 ┃ ┣ 📜category.png
 ┃ ┣ 📜exhibition.png
 ┃ ┗ 📜product.png
 ┣ 📂stories
 ┃ ┣ 📜Footer.js
 ┃ ┣ 📜Footer.stories.js
 ┃ ┣ 📜Header.js
 ┃ ┗ 📜Header.stories.js
 ┣ 📜.DS_Store
 ┣ 📜App.css
 ┣ 📜App.js
 ┣ 📜App.test.js
 ┣ 📜index.css
 ┣ 📜index.js
 ┣ 📜logo.svg
 ┣ 📜reportWebVitals.js
 ┣ 📜setupTests.js
 ┗ 📜store.js

 

Demo

https://angrydoggaebi.github.io/fe-sprint-coz-shopping/

 

화면 구성과 기능

-메인 페이지

main page(左), 햄버거 모달(右)

 

- 상품 리스트 페이지

상품 리스트 페이지

 

상품 리스트 페이지 동작 시연 화면

 

- 북마크 페이지

북마크 페이지(左), 북마크 아이콘과 toast 동작 시연화면(右)

 

- 상품 모달 창

상품 클릭시 모달 띄우기 (북마크 사용 가능)

 

 

 

고민했던 부분과 해결방법

- 모달 창에서 북마크 눌러도 리렌더링 되지 않는 문제

모달 창에서의 북마크 동작이 정상 작동하지 않았다. 상품을 클릭하고 모달이 뜬 후 아이콘을 누른 처음 한 번만 동작하고 그 후에는 모달을 닫았다가 다시 열지 않으면 모달창에서는 북마크 기능을 사용할 수 없었다.

내 코드의 구조는 사용자가 클릭한 북마크 리스트를 배열의 형태로 localStorage에 담아 다음 접속시에도 북마크 기록이 남아있도록 되어있는데, 북마크 리스트의 상태관리는 redux의 store.js에서 가능하게끔 되어있다. 

처음엔 모달 컴포넌트에서 북마크 리스트를 가져올 때 localStorage에서 받아오도록 했었다. 이 부분이 해결의 열쇠였고, localStorage가 아닌 redux store에서 리스트를 받아와 사용하도록 하니 문제가 해결되었다. 사용자의 클릭에 따라 북마크 리스트에 상품을 넣을지 말지가 결정되어야 하니 지금 생각해보면 당연히 local에서 받아오는게 맞지만, 코드를 짜고있을 땐 화면에 보이는 북마크 아이콘의 색을 결정하는 부분(이미 북마크 되어있으면 노란 별, 북마크 되어있지 않으면 회색 별 아이콘)을 먼저 구성하느라 후에 일어날 상태 변화를 생각하지 못 한 채 데이터를 그려주기 위한 코드를 짠 듯 하다. 

 

 

-  처음 접속 시 (localStorage가 비었을 때) 데이터 못 받아오는 문제 

 

분명 서버에서 api 받아오는 부분의 코드엔 아무 문제가 없는데도 localStorage가 깔끔하게 비어있는 경우였다. 이게 처음 데이터 받아오면서 다 실험 해 보았고 잘 받아오는걸 확인하고 진행을 했는데 중간에 갑자기 안 되어서 나를 당황스럽게 했었다. 심지어 http://localhost:3000/bookmark(북마크 페이지)로 한 번 진입했다가 http://localhost:3000/(메인페이지)로 돌아오면 데이터가 받아와지는 신비로운 경우라 머리를 많이 쥐어뜯었는데, 결론부터 이야기하자면 api 호출은 아무 문제가 없었고, 내가 구상한 홈페이지 돌아가는 방식에 놓친 부분이 있었다. 

이번 프로젝트에서 local에는 전체 상품 리스트와 북마크 리스트 두 개의 key가 사용되었는데, 메인 페이지에서는 상품 4개와 북마크 최대 4개까지를 화면에 보여준다. 처음 사용자가 사이트에 접속하면 북마크가 비어있으니 상품 4개만 보여야 한다. 하지만 그렇다고 local에 북마크 key가 없어도 되는건 아닌데, 이 부분을 간과하고 상품 key만 받도록 되어 있었던 거다. 내가 짠 코드는 app.js에서 api를 받아올 때는 local에 북마크 key가 없으면 아무 동작 없이 그냥 넘어가게끔 되어있었고, 메인화면에 북마크 리스트를 그리는 컴포넌트에서는 북마크 key를 이용해 local에 있는 북마크 리스트를 가져오게끔 되어있으니, 상품리스트만 있는 local에서 북마크를 찾게 되어 페이지가 오류가 났던 거다. 

즉, 가장 상위 컴포넌트이자 데이터를 받아오는 컴포넌트인 app.js에, local에 북마크 key가 없으면 없는 상태로 두는 것이 아니라, 빈 배열을 값으로 key를 저장하도록 코드를 짜니 해결되었다. 

 

 

- api 호출 시 http로 호출해야 하는데 https로 호출 되는 문제

이건 배포를 위해 빌드하니 생긴 문제인데 api를 받아올 때 http로 받아오지 않고 https로 받아오려 하는 문제이다. 때문에 오류가 난다. 다른 분도 비슷한 상황이신 분이 계셔 제공되는 서버의 문제라고 판단, 서버를 사용하지 않고 데이터를 받아오기 위해 제공되는 데이터를 전부 복사하여 새로운 파일에 넣고 그 파일에서 호출하도록 만들었으나, 왜인지 같은 문제가 발생. 아직도 정확한 원인을 몰라 아쉬운 부분이긴 한데 데이터가 담긴 파일 주소인 'dummy/datalist.json'을 'http://localhost:3000/fe-sprint-coz-shopping/dummy/datalist.json' 으로 http를 포함한 전체 주소로 명시해주니 해결되었다. 

 

 

 

- 배포 시 일부 화면 그려지지 않는 문제

데이터까지 받아오는걸 확인하고 이번에야 말로! 를 외치며 배포한 사이트에 접속했으나 보이는건 header와 footer 뿐... (header와 footer가 겹쳐있는건 내가 footer를 상품 컴포넌트 아래 붙도록 만들었기 때문) 이쯤 되니 속이 뒤집어지는 것 같았지만 불굴의 의지로 원인을 찾았고, 다행히 생각보다 빨리 해결했다. 배포를 gh-pages로 했는데, gh-pages는 BrowserRouter 대신 HashRouter를 사용하는걸 권장한다고 한다. 다른 방법으로는 BowserRoter에 basename을 넣는 방법이 있다고 해서 비교적 간단해보이는 후자부터 도전했고, 배포용 주소의 끝부분을 basename에 넣으니 바로 해결되었다. ㅠㅠ

 

후기

웹페이지 라는 것을 처음부터 끝까지 혼자 만들어본 것이 처음이다. 전체적인 동작들은 크게 어렵지 않았지만 자잘한 요소들에 발이 묶이는 경우가 많았다 (css같은..). git도 제대로 써보는건 처음이라 처음엔 아주 엉망진창이었다. 브랜치 안에 브랜치 안에 브랜치를 만들어 마트료시카 브랜치를 만들지 않나... api 실험한다고 캐시를 삭제해 깃헙에서 로그아웃된 상태로 pr이 안 된다고 고민하질 않나... 다른 부분보다 api 관련된 부분이 시작부터 마지막까지 나를 너무 괴롭혀 정말 눈물만 안 흘렸지 이 길이 내 길이 아닌가 수준까지 갔었다. 그래도 한 번 해보면 다음번엔 훨씬 쉽게 할 수 있다는걸 안다. 그리고 재밌다. 실력이 없어 속상하기도 하고 해결되지 않는 오류에 고통스럽기도 하지만 하기 싫다가 아닌 더 잘 하고싶다고 생각하니 재능은 몰라도 취향에는 맞나보다. 

 

아쉬운 점은 css 단위를 px로 작성해 아마 내 컴퓨터와 다른 사이즈의 컴퓨터에서 보면 화면이 예쁘게 안 보일 것 같다. 다음엔 rem같은 단위를 써봐야겠다. 그리고 css를 위해 styled-component를 사용했는데 공통되는 부분도 각각의 컴포넌트에 따로 적용해서 앞으로 GlobalStyle로도 사용해보고싶다. 하고싶은건 많고 시간은 적고 머리는 안 돌아가는 멋진 인생! 

 

 

 

github 주소 : https://github.com/AngryDoggaebi/fe-sprint-coz-shopping