-
[12월 4주차] 백엔드와의 첫 협업 후기 및 트러블 슈팅 (feat. 항해99 6주차 미니 프로젝트)WIL 2022. 12. 26. 00:21
이번주는 처음으로 백엔드와 협업해본 주차였다. 어찌보면 CRUD 자체는 지난 주와 크게 다르지 않았지만 그 외적인 부분에서 구현해야할 기능들이 있었다. 로그인 및 회원가입 기능과 게시글 좋아요 기능이 추가되다보니 이 부분에서 새롭게 배우는 부분이 많았다. 먼저 이번주에 완성한 결과물은 다음과 같다.
유튜브 링크
http://hh99-mini5-codingvibe.s3-website.ap-northeast-2.amazonaws.com/
코딩할 때 좋은 플레이리스트라는 컨셉으로 코딩할 때 발생하는 상황에 따라 카테고리를 정하였다. 메인페이지에는 카테고리와 좋아요를 많이 받은 플레이리스트 Top3가 나온다.
카테고리별 페이지다. 옆에 메뉴바는 position:fixed로 만들어서 스크롤해도 올라가지 않는다. 헤더의 경우 로그인한 경우 "OO님 환영합니다!" 라는 문구와 함께 로그아웃 버튼, 회원탈퇴 버튼이 생기고 로그아웃한 경우 로그인 버튼이 생긴다. 게시물들의 유튜브 썸네일이 보이도록 하였다.
게시물 상세페이지다. 자신의 게시물 및 댓글의 수정과 삭제를 할 수 있으며, 로그인을 하지 않은 경우와 타인의 게시물 및 댓글인 경우 alert가 나타난다.
1. 상황에 맞는 alert 띄우기
가장 먼저 힘들었던 것은 상황에 따른 alert를 띄우는 것이었다. 로그인을 한 경우와 안 한 경우, 자신의 게시물 및 댓글인 경우와 아닌 경우에 따라 띄우는 alert가 달랐기 때문이다. 또한 케이스마다 성공한 경우 페이지를 이동해야하고, 에러인 경우에는 alert만 띄우고 그 페이지에 그대로 머물러야하기 때문에 이러한 케이스들을 모두 다 처리하는게 처음에는 너무 어렵고 버거웠다. 여기서 문제점은 extrareducer에서 에러를 캐치했을 때 바로 alert를 띄우거나 페이지이동을 해야한다는 것이었다. 불필요하게 initalState에다 error변수를 만든 후 에러 시 에러메시지를 여기다 할당하고 useSelector를 사용해서 해당 페이지에 그 error 변수를 가져와서 error 변수에 에러메시지가 할당될 때 alert를 띄우는 식으로 했기 때문에 꼬인 것이었다. 결론은 try / catch의 역할을 하는 구조를 두 번을 쓰면서 꼬이게 된 것었다. extrareducer에서 성공 시와 에러 시에 각각 바로 처리를 해버리니 해결되는 문제였다. 이런 식으로 하니 에러 시에 서버에서 보내주는 상황에 따라 다른 에러 메세지를 바로 화면에 alert로 띄울 수 있어서 매우 편리하고 좋았다.
두 번째 alert 관련 난관은 유저가 로그인을 한 경우와 안 한 경우에 따라 다르게 alert를 띄우는 것이었다. 유저가 로그인을 하지 않은 경우에도 메인페이지 및 상세페이지를 볼 수 있었기 때문이었다. 그렇기에 로그인을 하지 않은 유저의 경우 게시물 수정 및 삭제 버튼을 눌렀을 때나 좋아요 버튼을 눌렀을 때, 혹은 댓글 등록 / 수정 / 삭제 버튼을 눌렀을 때 "로그인 후 이용가능합니다."라는 메세지를 alert로 띄울 필요가 있었다. 이를 위해서 상세페이지에 useEffect를 사용하여 페이지가 마운트될 때마다 로컬스토리지에 저장된 유저 id가 있는지 체크한 후, 즉 로그인 상태인지 체크한 후 false였던 useState로 만든 isLogin 변수를 로그인 한 경우 true로 바꾸어 사용하였다. 이를 통해 isLogin이 false인 경우에 "로그인 후 이용가능합니다."라는 메세지를 띄울 수 있었다.
또한 로그인을 한 경우에 당연히 자신의 게시물 및 댓글을 수정이나 삭제하는 것이 가능하지만 타인의 게시글 및 댓글을 수정 및 삭제하려고 할 때 alert를 띄울 필요가 있었다. 이 경우에는 수정 및 삭제 요청을 서버에 보내고, 서버에서 토큰 값을 비교해본 뒤에 일치하지 않으면 에러 메세지로 "작성자만 삭제할 수 있습니다."라는 메시지를 보내주면 그 내용을 그대로 alert를 하는 방식을 사용했다. 그런데 게시물 수정의 경우에는 게시물에 딸린 수정 버튼을 눌렀을 때 수정 요청을 보내는 것이 아니라, 수정 페이지로 이동한 뒤에 수정을 하고나서 수정 요청을 보내는 것이다보니, 수정 페이지를 들어가기 전에 게시물에 딸린 수정 버튼을 눌렀을 때 작성자가 아닌 경우에 alert를 띄울 필요가 있었다. 이를 위해서 게시물 수정의 경우에는 버튼을 눌렀을 때 로컬스토리지에 저장된 username과 해당 게시물의 username을 비교하여 alert를 띄우도록 하였다. 어차피 회원가입시 username에 대한 중복체크를 했기 때문에 중복된 username은 존재할 수 없으므로 토큰이 아닌, 로컬스토리지 값으로 단순비교를 하더라도 상관이 없기 때문이다. 그런데 지금에서야 드는 생각은 게시글 삭제와 댓글 수정 및 삭제 역시 굳이 서버에 요청하지 않고 로컬스토리지에 저장된 username과 게시물 및 댓글 작성자의 username을 비교해서 alert를 띄울 수 있었을 것이라는 생각이 들었다. 아무래도 서버쪽 요청을 최소화하는 것이 비교적 비용이 덜 드는 방식이 아니였을까?
그리고 게시물 및 댓글 수정 및 삭제와 관련하여 추가적으로 시도해보고 싶은 부분은 애초에 수정 및 삭제를 시도하는 username과 해당 게시글 및 댓글의 username이 일치하지 않으면 애초에 수정 및 삭제버튼이 나타나지 않게 하는 방식이 최선이라는 생각이 든다. if문을 사용하여 나타나는 버튼이 달라지도록 다음에는 시도해봐야겠다.
2. 비효율적인 렌더링되는 것
이번에 만든 coding vibe의 경우에는 게시물마다 좋아요 기능을 추가하였다. 좋아요 기능 자체는 큰 문제없이 true / false에 따라 보여주는 하트 및 좋아요 숫자가 달라지게 구현할 수 있었다. 다만 하트 부분이 컴포넌트로 분리되지 않다보니 유저가 좋아요를 누를 때마다 페이지 전체가 새로고침 수준으로 재렌더링되는 것이었다. 그래서 유저가 좋아요를 눌렀는지를 알 수 있는 checkPostLike와 좋아요 개수인 likeCount를 게시물 데이터를 불러올 때 따로 initalState에 저장하고 하트에 대한 부분을 아예 컴포넌트로 분리하여 처리하였다. 그래서 유저가 하트를 누를 때마다 게시물 좋아요 post요청을 thunk에서 보내고 checkPostLike와 likeCount를 불리언 값에 따라 변경하여 화면에 반영하도록 하였다. 그런데 이렇게까지 하였는 데도 화면이 자꾸 전체적으로 렌더링되는 문제가 발생하였는데 그 원인은 initalState에 있는 isLoading를 쓰는 방식에 있었다. 강의 내용에 따라 게시글이든 댓글이든 좋아요든 thunk와 extrareducer를 쓰는 경우에 무조건 pending / fulfilled / rejected에 따라 isLoading 값을 변경하였고, isLoading값이 true일 때, 즉 서버요청중인 pending의 경우 화면에 "로딩중"이라는 글자를 띄우게 하였었다. 그런데 이것으로 있해 pending일 때의 시간이 매우 짧은 좋아요의 경우에도 아주 잠깐 로딩중이라는 글자를 띄우게 되면서 화면이 깜박이는 현상이 나타난 것이었다. 그래서 isLoading값이 true일 때 로딩중이라는 글자를 띄우는 코드를 지우자마자 화면이 깜빡이는 현상이 사라졌다. 이를 통해 로딩중이라는 화면을 띄울 때는 꼭 제한적으로 필요한 경우에만 사용해야 한다는 것을 알게 되었다.
한편으로 좌측에 있는 메뉴바 역시 컴포넌트로 분리하여 재렌더링이 되지않도록 하여, 정말 데이터가 바뀌는 부분만 재렌더링이 되도록 완성도 높게 마무리할 수 있었다.
3. 로그아웃
로그아웃의 경우에는 정말 고민을 많이 한 부분이었다. 로그아웃 버튼을 눌렀을 때, 로컬스토리지에서 토큰값을 삭제하는 것까지는 할 수 있었으나, 헤더에서 "OO님 환영합니다"라는 문구가 사라지고 로그인 버튼이 생겨야하는데, 이부분을 useEffect를 쓰다보니 새로고침을 해야만 반영이 되었었다. 또 다른 문제점은 게시물 상세페이지에서 로그아웃을 한 경우 좋아요 하트가 빈하트로 바뀌어야하는데 이 부분이 반영이 안되었다. 고민하다가 다른 조원이 로그아웃시 새로고침을 자동으로 시켜주면 되지 않느냐고 말하였고 window.location.reload(true)를 하자 바로 해결되었다. 사실 새로고침을 생각하지 않은 것은 아니지만, 뭔가 리액트에서 새로고침을 매우 제한적으로 써야한다는 생각이 있어 시도해보지 않았었다. 그런데 찾아보니 네이버 같은 사이트에서도 전부 로그아웃 시에 새로고침이 된다는 것을 보고 바로 시도하였고 해결되었다!
4. 결과물
사실 이번주는 힘들었던 점이 한 조에 프론트가 2명이었는데, 다른 한 분이 진도를 따라오는 것에 어려움을 겪고 계신 분이라 기능 구현의 경우 거의 대부분 혼자해야했기에 힘든 부분이 많았다. 로그인/회원가입부터 게시물 및 댓글 기능까지....막판에는 회원탈퇴까지 시도해보았는데 그 모든걸 전부 혼자하면서 힘든 점도 많았지만 그만큼 실력이 1주일만에 폭풍 성장했다는 게 느껴졌다. 또 마지막날에 제출 후 발표를 하고 나서 기술 매니저님이 너무나 칭찬을 많이 해주셨다. 특히 로그인 여부나 작성자 여부에 따라 권한들을 하나하나 세심하게 처리를 한 부분을 높게 사주셨고, 반나절 만에 좋아요 기능 및 에러 관련하여 피드백한 부분을 필요한 부분에 딱딱 넣어서 깔끔하게 해결한 부분을 칭찬해주셨다. 또 이력서에 당당히 실어도 된다고 하셔서 정말 뿌듯하고, 현업 수준에서 봐도 좋을 정도의 프론트라고 극찬을 해주셨다ㅠㅠ! 예상치 못한 극찬을 받으니 그간 고생했던 것에 보상받는 것 같아 기뻤고 정말 뿌듯하엿다. 힘들 때가 많았는데 과거가 미화되면서 또 다시 코딩을 열심히 할 동기부여가 되었다ㅎㅎㅎㅎㅎ
5. 커뮤니케이션
마지막으로 이번주에 느낀 것은 내가 하는 생각이 무조건 맞다고 생각하지 말고 다른 사람들의 의견을 충분히 귀기울여 듣고 논리적으로 협의하자는 것이었다. 항해를 하면서 초반에는 사람들의 의견을 딱 들었을 때 내 의견이 더 맞다고 생각하면 나도 모르게 강력하게 내 주장을 말할 때가 있었는데, 지난주를 겪고 보니 모든 사람들의 의견의 다 의미가 있고 소중하다는 것을 알게 되었다. 처음들었을 때 이해가 안갔을 때 차분히 다시 물어가며 의견을 조율해나가는 과정에서 내가 놓치고 있던 것들을 많이 알게 되었고, 소통의 중요성을 깨닫게 되었다.
'WIL' 카테고리의 다른 글
[12월 5주차] 인스타그램 클론 코딩 (feat. 항해99 7주차 클론 코딩주차) (0) 2023.01.09 [1월 1주차] 실전프로젝트 일주일 후기 (feat. 항해99 8주차 실전 프로젝트) (3) 2023.01.09 [12월 3주차] 리액트 협업 트러블 슈팅 (feat. 항해99 5주차 리액트 심화주차) (0) 2022.12.18 [12월 2주차] 리액트 라이프 사이클과 hooks (feat. 항해99 4주차 리액트 숙련주차) (0) 2022.12.12 [12월 1주차] 리액트로 Todo 리스트 페이지 만들어보기 (feat. 항해99 3주차 주특기 입문 주차) (0) 2022.12.05