프리미엄 과일 부티크 커머서 사이트인 "마담주"를 클론코딩 해보았습니다!
21.08.30 ~ 21.09.10
FE : 김현재(me!), 정행운, 조성환
BE : 김장호, 최현수
FrontEnd
Javascript
, React(CRA)
, React-router-DOM
, SCSS
BackEnd
Phython
, Django
,MySQL
, AqueryTool
, RESTful API
, bcrypt
,
Common
POSTMAN
Communication
Slack
, Zoom
, Trello
, Github
, Git
, Notion
팀원들과 페이지 별로 역할을 분담해 기능을 구현했고, 내가 담당한 페이지는 ✅ 표시를 해두었다.
✅Main page
✅List page
Detail page
Cart page
Login page
& Signup page
Navigation bar
Footer
상단과 하단 부분에 carousel을 활용하였으며, scroll event 및 video를 활용하여 동적인 페이지로 구성해보았다.
무한 스크롤 기능을 활용하여, 스크롤이 client view의 가장 끝 지점에 도달했을 시 자동으로 fetch받아올 수 있도록 구현하였다.
BE 측에서 pagenation URI를 페이지별로 분리해주셔서 (1페이지,2페이지 이런식으로) 보다 쉽게 로직을 만들 수 있었다✨
state = {
page: 1,
};
// pagenation 전용 fetch - scroll 끝 지점에 도달하면 이 함수를 호출하여 추가 페이지를 fetch한다
handlePageFetch = () => {
if (this.state.page < 3) {
fetch(
`${PRODUCT_LIST_API}page=${this.state.page}&tag=${this.state.filter}`
)
.then(res => res.json())
.then(items => {
const fetchData = items;
const mergeData = this.state.items.products.concat(
...fetchData.products
);
const newObj = { products: mergeData };
this.setState({ items: newObj });
console.log(this.state);
});
}
};
handleScroll = () => {
const scrollHeight = document.documentElement.scrollHeight;
const scrollTop = document.documentElement.scrollTop;
const clientHeight = document.documentElement.clientHeight;
if (scrollTop + clientHeight >= scrollHeight) {
this.setState({ page: this.state.page + 1 });
}
};
componentDidMount() {
this.handleFetch();
window.addEventListener("scroll", this.handleScroll);
}
// 페이지가 넘어가야될 경우에만 fetch 받아오도록 CDU활용
componentDidUpdate = (prevProps, prevState) => {
if (this.state.page !== prevState.page) {
this.handlePageFetch();
}
};
메인 페이지에 carousel이 2개가 들어가다보니 상당히 심적으로 챌린지였다.
역시 예상한대로 처음 carousel 구현에 20시간이나 소요되었다..🥲
그래도 역시 한번 만드니까 원리를 확실히 이해하게 되었고, 이후 하단 carousel을 만드는 것은 1시간?도 걸리지 않았다.
역시 이것저것 만들어보아야 속도가 붙는구나라는 것을 깨달았다.
처음에 무한스크롤관련 로직을 CDM하나로 해결하려고 했는데 역시 택도 없었다..🥲
첫페이지 fetch가 되지도 않은 상황에서 동시에 두번째 페이지를 받아 가공하는 로직을 짜놓으니..리액트는 자꾸 에러를 던질 뿐이었다.
CDU은 잘못 쓰면 컴퓨터가 무한 네트워킹에 빠지다보니 무서워서 최대한 안 사용하고 싶었는데..무한스크롤을 만들려면 피할 수 없는 존재였고..
어찌어찌 fetch함수를 두개로 쪼개고, 각 상황 별로 분리되어 fetch되도록 CDU안에 조건문을 사용하니 우려했던거에 비해 CDU는 이쁘게 작동하게 되었다✨
앞으로 CDU는 겁먹지 않고 사용할 수 있을 것 같다.
FE & BE가 공동의 목표를 잡고 세부 계획을 세우기 위해 초기에 다른 팀에 비해 시간 투자를 많이 했다.
처음에는 살짝 우려가 되었던 것이 회의를 많이하다보니 다른 팀보다 구현 진도가 많이 뒤쳐졌었기에 구현을 많이 못해낼까봐 우려되었었다.
허나 기초공사를 탄탄히 한 덕분인지 merge를 할때도 큰 conflict가 일어나지 않았고, backend 서버와 첫 통신을 할때도 fetch구조를 많이 고쳐야하는 등의 불상사가 일어나지 않았다.
이러한 자잘한 수정들이 생략되어서 오히려 후반기에 갈수록 구현 속도가 매우 빨라졌고, 결국 둘째주 수요일에는 큰 구현은 모두 완료하여 우리끼리 자체 study session을 진행할 정도로 "시간적 여유"와 "기능 구현"이라는 두마리 토끼를 모두 얻을 수 있었다.
장호님의 제안으로 특별한 session을 개최하게 되었다. 이름하여 "FE & BE cross-study session"으로, 프론트엔드와 백엔드가 각자 어떤식으로 workflow가 이루어지는지를 공유하는 세션이다.
workflow뿐만 아니라, ERD 모델링 분석 및 파이선 view 해석하기, javascript fetch API로직 처리과정 등 FE, BE간 커뮤니케이션에 활용할만한 교양강좌(?)를 진행하여 각 분야에 대해 좀 더 자세히 이해하는 시간을 가졌다.
이 시간 덕분에 전체적인 project schedule을 어떻게 가져가야할지, 그중에서도 (내가 속한)FE는 어떻게 탄력적으로 스케줄을 대응할 수 있을지에대한 답을 약간 얻게 되어 매우 뜻깊은 시간이었다✨
리액트를 다른 팀원들 보다 조금 수월하게 사용한다고 판단했기에, 첫주에 내 작업을 다 끝내고 둘째 주에 팀원들을 도우며 부수적인 업무를 하는 것으로 계획을 세웠었다.
그러나, 내가 할 최소한의 일을 끝내자마자 긴장이 풀렸는지 체력적으로 매우 힘든 시간이 이어졌다. 체력적으로 힘들어지니 기존에 갖고 있던 텐션이 떨어졌고, 팀원을 단순히 support 하는 두번째 주가 지나갔다.
두번째 주가 끝나갈 무렵, 팀원들이 추가구현 하고 싶었던 내용을 적어둔 카드가 우연히 눈에 잡혔다. 두번째 주를 만약, 팀원들이 구현하고 싶었던 추가적인 요소들을 구현하는데 추가했으면 어땠을까 라는 생각이 들었다.
혹여나 하는 생각에 다른 팀원한테 해당 팀원의 추가구현 요소를 내가 시도해봐도 될지 물어보았는데, 예상과는 달리 "그럼 정말 좋지요!"라는 대답이 돌아왔고 그순간 '아차!'싶었다..남의 작업물을 건든다는 것이 부담스러워서 내가 맡은 파트가 아닌 곳의 추가구현은 최대한 건드리지 말아야지라고 생각했지만, 의외로 누군가는 그러한 도움을 반기기도 한다는 것을 너무 늦게 알았다.
이 경험을 양분 삼아, 다음 작업 때는 (혹시 팀원이 OK한다면) 팀원이 원하는 추가구현 사항을 내가 만들어 보아도 될지 보다 적극적으로 물어봐야겠다.
나의 장점이자 단점인 "빠른 판단"이 팀원들을 힘들게 하지 않았을까 라는 생각에 마음 한켠이 살짝 걱정된다.
다들 처음하시는거니까 천천히 보고, 이해할 여유를 충분히 드렸어야 했는데..다같이 해야만 하는 작업인데 내가 체력적으로 많이 부쳐서 빨리 끝내고 싶은 마음에 조금 서둘렀던 경향이 없잖아 있었던 것 같다(내가 다 해버린다거나..끝무렵의 마이크로매니징이나..)
공동 회고 세션에서는 팀원들이 내가 그렇게 해준게 도움, 의지가 되었다고 하지만..그건 거시적인 평가일 수도 있고, 순간순간은 살짝 불편하시지 않았을지 우려된다.
나의 그런 미숙한 모습도 덤덤히 받아주신 팀원 분들께 정말 감사의 마음 뿐이다. 그렇기에 경각심을 가지고 "정말 필요한 순간"을 제외하고는 팀원들을 의지하고 맡기자! (그리고 체력관리..필수..✨체력이 성격이 되지 않도록 하기)