※이 프로젝트는 사이트의 디자인만을 차용하고,
모든 코드는 COPY한 것이 아니라 설계부터 자체적으로 하였음을 명시합니다.
프로젝트 기간
2022.11.30 ~2022.12.04 (5days)
그라폴리오 사이트를 모델링 사이트로 선정한 이유
우리 팀은 세션 때 배웠던 이론을 바탕으로 심화, 응용하여 개발자로서 성장할 수 있는 사이트를 고르는 것을 최우선의 목적으로 두었다. 따라서 해보았던 기능들을 다시 적용해볼 수 있으면서도 새로운 기능을 학습할 수 있는 그라폴리오 사이트를 선정하게 되었다.
사이트의 성격
사진 공유 플랫폼으로, 누구든 사진작가가 되어 자신의 작품을 업로드하여 소통할 수 있다.
팀원소개
Front-end
한혜선, 김정현, 오다원
Back-end
박수호, 송인찬
기술 stack
Front-end : React, Sass
Back-end : Node Express, Mysql, AWS
컨벤션
포토폴리오 renewal 사이트 url
협업방식
Notion에서 칸반보드와 타임라인을 이용하여 티켓으로 일정 관리
Daily stand up meeting(PM 5:00) : 어제 작업한 사항, 오늘 해야할 사항 공유
Slack : 공지사항 전달
vscode liveshare : 실시간 코드 공유 및 피드백
git/github, zoom, google meet : 실시간 코드 리뷰, 함께 에러 해결
내가 담당한 부분
1차 프로젝트 코드 리팩토링, 게시물 상세페이지 중 좋아요, 게시물 삭제, 댓글 삭제 기능 추가
좋아요 기능
//좋아요 버튼을 누르면
const clickLike = () => {
// 좋아요 카운트 증가
if (token && likeBtn === false) {
fetch('http://' + URI + ':8000/sympathy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: localStorage.getItem('token'),
},
body: JSON.stringify({
posting_id: id,
sympathy_id: 1,
}),
})
.then(res => res.json())
.then(res => {
setLikeCnt(res.getSympathiesCount[0].sympathy_cnt);
setLikeBtn(true);
});
} else if (token && likeBtn === true) {
// 좋아요 카운트 감소
fetch('http://' + URI + ':8000/sympathy', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: localStorage.getItem('token'),
},
body: JSON.stringify({
posting_id: id,
}),
})
.then(res => res.json())
.then(res => {
setLikeCnt(res.getSympathiesCount[0].sympathy_cnt);
setLikeBtn(false);
});
}
};
const likeCheck = () => {
if (token) {
//로그인을 했을 시
return (
<button className="detail-icon">
<img
src="https://cdn-icons-png.flaticon.com/512/1062/1062573.png"
alt=""
onClick={() => {
clickLike();
}}
/>
</button>
);
} else {
//로그인을 안했을 시
return (
<button className="detail-icon">
<img
src="https://cdn-icons-png.flaticon.com/512/1062/1062573.png"
alt=""
onClick={floatLoginModal}
/>
</button>
);
}
};
좋아요 기능을 만들 때는 생각보다 많은 어려움이 있었다.
첫 번째, 전에 좋아요 눌러놓았던 상태를 어떻게 알고, 유지할 것인가? 이것은 전에 팔로우/팔로잉 버튼을 구현하셨던 팀원께 도움을 받아, back-end에서 버튼의 상태를 fetch로 받아오도록 하여 해결하였다.
두 번째, 좋아요를 누를 때 처음에는 버튼이 카운트업/다운이 되지 않고, 두 번째 부터 되는데 이것이 왜 발생하는 것이며, 어떻게 고칠 것인가? 이전에는 버튼의 상태를 바꾸는 것을 따로 useEffect로 빼서 그것이 실행된 후, likeCheck 함수가 실행되게 하였는데, 이렇게 하다보니 useEffect 다음 바로 likeCheck함수가 실행이 되지 않았기 때문에 처음에는 카운트업/다운이 안되었던 것이다. 따라서 '이것을 하나로 합쳐야겠구나'라고 생각하게되었고, 버튼을 누르고 응답을 받은 후에 버튼의 상태가 변경되게 만들었다. 결과는 성공적이었다.
함수안에 조건문
좋아요 기능을 만들면서 알게된 방법이 하나 있는데, 바로 위 코드의 likeCheck 함수와 같이 함수 안에서 조건문을 써서 서로다른 onClick 상태를 가질 수 있게하고, 이 함수를 좋아요 아이콘 위치에서 불러와서 사용할 수 있다는 것이었다.
이 방법을 몰랐을 때는 로그인 했을 때와 로그인 하지 않았을 때를 분리하여 얼럿창을 어떻게 띄워야할지 굉장히 난감했는데, 팀원으로부터 알게되어 바로 적용하였다. 이 경험을 통해 팀원들의 장점, 혹은 배울점을 가져와 흡수하는 것도 나를 발전시킬 수 있는 방법이 된다는 것을 느낄 수 있었다.
게시물 삭제
//게시물 삭제
const deleteContent = () => {
alert(
`작품을 정말 삭제하시겠습니까? 작품을 삭제하면 댓글 정보까지 영구히 삭제됩니다.`
);
fetch('http://' + URI + ':8000/works/feed/' + id, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: localStorage.getItem('token'),
},
body: JSON.stringify({ posting_id: id }),
});
alert('작품이 삭제되었습니다.');
navigate(`/channel/${userId}`);
};
내 아이디와 게시물 작성자의 id를 비교하여 같은 사람일 때만 메뉴 버튼이 나타나도록 하였고, 그 버튼을 누르면 삭제 할 수 있는 드랍다운 메뉴가 나타날 수 있게 하였다.
그런데 게시물을 삭제하기 위한 fetch를 작성하고, 통신하는 중에 요청이 가지 않는 에러가 발생했다. 그래서 팀원 전체와 같이 google meet에 모여서 코드를 보며 문제 상황을 파악하였다. 원인은 body였다. back-end에서 보내준 명세에 body값이 있었지만, 내가 볼 때 body에서 보내주는 값과 fetch uri에서 보내주는 id값이 중복된다고 판단하여 그렇게 말씀을 드렸더니, body를 없애신다고 하셨다. 그래서 body를 없애고 통신을 했는데 요청이 가지 않았던 것이었다.
이유는..?
back-end에서는 지우셨다고 했지만, body없이는 요청이 가지 않으니, 혹시나 하고 다시 body에 값을 넣었더니 요청이 올바르게 갔다. 아쉽게도 시간이 부족해 이것의 정확한 이유는 밝혀내지 못했지만, back-end에서 body 데이터가 완벽히 지워지지 않았을 확률이 높다고 생각한다. 다음 프로젝트 진행 시에는 이러한 사소한 요청이라도 문서화하여 조금 더 명확하게 진행해야겠다는 생각이 들었다.
댓글 삭제
//댓글 삭제 fetch
const deleteReply = () => {
alert('댓글을 삭제하시겠습니까?');
fetch('http://' + URI + ':8000/comments', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: localStorage.getItem('token'),
},
body: JSON.stringify({ comment_id: id, posting_id: posting_id }),
})
.then(res => res.json())
.then(res => setDeletedReply(res.deleted_comment_id));
};
return (
<>
{deletedReply !== id && (
<div className="detail-reply-card">
<div className="reply-top-wrapper">
<div>
<div className="detail-reply-writer">{kor_name}</div>
</div>
{idCheck == user_id && (
<span className="menu" onClick={menuClick} />
)}
{menuBtn && (
<div className="selectMenuWrapper">
<div className="selectMenu">수정</div>
<div className="selectMenu" onClick={deleteReply}>
삭제
</div>
</div>
)}
</div>
<div className="detail-reply-content">{comment}</div>
<div className="detail-reply-date">{created_at}</div>
</div>
)}
</>
);
};
mission: 댓글을 삭제하고 화면에 바로 반영시켜라!
댓글 삭제는 전반적으로 게시물 삭제와 비슷했다. 다만, 다른점이 하나 있었는데, 삭제된 댓글의 아이디를 응답으로 받아왔다는 것이다. 그 이유는 댓글 삭제 버튼을 눌러서 DB에서 댓글을 삭제해도 화면에서 지워지는 모습이 렌더링이 되지 않았기 때문인데useEffect를 이용해서 댓글을 삭제하는 fetch 함수를 작성하였다면, 의존성 배열에 댓글 배열을 넣으면 되지만 함수형이었기 때문에 넣을 수 없었다.
따라서 나는 삭제된 댓글의 아이디를 받아올 수만 있다면 그것을 front-end에서 먼저 클라이언트에게 보이지 않게 해주면 된다고 생각했고, 그 방법은 성공적이었다.
하지만 이 방법에는 지켜야할 사항이 존재하는데, 응답을 받아오기 전에 front-end에서 보이지 않게 해버리면, back-end에서 제대로 삭제가 되지 않았음에도 댓글이 사라져버리는 것이기 때문에 응답을 받아온 후, 처리할 수 있도록 하여야한다는 것이다. 이 사항만 지키면, 누구든 성공적으로 댓글을 삭제할 수 있을 것이다!
5일동안 리뉴얼을 진행하며,
컨벤션의 중요성
이번 프로젝트에서는 변수 이름을 정하는 방식이라거나, commit 메시지, 스타일 등의 컨벤션등을 이전 프로젝트보다 자세하게 정하여 사용하였다.
이전 프로젝트에서는 컨벤션을 얼마나 자세하게까지 정해야하는지도 알지 못했고, 그렇기에 상세하게 정하지 못했다. 그런데 프로젝트들을 실제 진행해보니 서로 다른 방법으로 개발을 하고 있어, 소통이 어렵다는 것을 느꼈고 컨벤션의 중요성을 알게되어 이번에는 조금 더 자세하게 컨벤션을 정하여 사용하게되었다. 확실히 상세한 컨벤션을 통해, commit 이력을 파악하는 것도 쉽게 되었고, 팀원들의 코드의 통일성이 생겨 보다 보기가 수월해졌다는 것을 체감했다.
따라서 컨벤션을 정하는 것과 지키는 것이 프로젝트에서 굉장히 중요하다는 것임을 알게되었기 때문에 앞으로 나에게 있을 다양한 프로젝트 들에서는 조금 더 컨벤션에 대하여 신경써야겠다고 생각하게되었다.
git rebase를 경험하다!
이전 프로젝트 들에서는 업데이트 된 코드를 합치는 방법으로 git merge방식을 사용하였는데, 이 방식은 commit 내역을 효율적으로 관리할 수가 없다는 단점이 있었다. 그래서 git rebase 세션을 들은 뒤, 우리는 이 방법을 적용해서 프로젝트를 진행해보기로 하였다.
git rebase를 이용해보니 처음엔 원하는 커밋을 pick해줘야 하는 방법이 너무 번거롭고, 불편했지만 계속 사용하다보니 훨씬 진화된 방법이라는 것을 체감했다. 그닥 중요하지 않은 commit들을 없앨 수 있었고, 시간의 순서로 정렬되어 보기가 굉장히 편해졌기 때문이다.
진화된 방법을 사용하는 것은 처음엔 어려울지라도 훨씬 효율적이다. 아무래도 많은 개발자들의 불편사항과, 고민들을 반영한 것이기 때문이다. git rebase를 통해, 차용하는 작은 방식의 차이로 효율적인 면에서 많은 차이가 발생할 수 있다는 것을 알게되었으며, 앞으로도 진화된 방법을 많이 사용해보며 나를 발전시켜야겠다는 생각이 들었다.
개선을 한다는 것은..
처음부터 프로젝트를 만들어본 경험은 여럿 있지만, 우리가 완성했던 프로젝트를 개선한 적은 처음이었다. 전에 작성한 코드들을 다시 뜯어보면서 시간이 많이 지나지는 않았지만 성장한 나를 발견할 수 있었고, 기능을 추가, 개선하는 작업을 통해 프로젝트에 대한 애정이 더욱 많이 생겼던 것 같다.
기한 안에 완성하는데만 그치지 않고, 개선 작업을 한 나와 우리 팀원들 모두 너무너무 칭찬한다!
'회고록' 카테고리의 다른 글
[JUSTCODE] FAST-FIVE 기업과제 프로젝트 회고록 (0) | 2022.12.27 |
---|---|
[JUSTCODE] 1, 2차 프로젝트 리팩토링 (2) | 2022.11.29 |
[JUSTCODE] 2차 프로젝트 회고 (2) | 2022.11.29 |
[JUSTCODE] 1차 프로젝트 회고 (3) | 2022.11.14 |
[JUSTCODE] 1개월차 회고 (0) | 2022.11.13 |