TIL21: React: Westagram 클론 마무리*

sunghoonKim·2020년 12월 11일
1

2주 동안의 위스타그램 클론. 2주동안 수 많은 삽질을 했다. 1차 프로젝트의 반이 지나 어느정도 리액트에 대해 고여버린 시점에서, 과거의 귀여웠던 삽질 기억을 되짚어본다.


리액트로 어떻게 옮기나요..

리액트를 시작하면서 가장 먼저 했던 것이, 기존에 작성했던 html, js, css 파일을 CRA의 형식에 맞게 옮겨오는 것. 어떻게 하는지에 대한 가이드가 잘 제공 되어서 별 다른 어려움 없이 옮겨올 수 있었다. 그리고 npm start를 실행시켰다.

오마이갓.
html 구조는 잘 받아와 졌는데, 화면에 스타일링이 다 망가져서 나타났다. 이것 때문에 고민을 1시간 가량 했던 것 같다. 주위 동기분들에게 물어봤으면 간단하게 답을 얻을 수 있는 문제 였었는데, 무슨 고집이었는지 혼자서 알아내려고 그 오랜 시간을 끙끙거렸다.

이유는, SPA의 구조에 있었다. SPA로 인해 index.js 에서 모든 하위의 컴포넌트들이 import로 연결된다. 그렇게 연결되는 컴포넌트는 각각의 CSS 파일을 import 하고 있다. 따라서, 모든 CSS 파일이 동시에 import 되어, 스타일링이 겹쳐 나타났던 것이다.

유독 나의 경우 겹치는 부분이 많았는데, 보통 클래스 네임을 주지 않고, 태그 이름으로 스타일링을 주었기 때문이다.

정말 겹칠 수 밖에 없는 식으로 스타일링을 했었다.

이 부분을 해결하기 위해 SCSS를 사용하였다. SCSS의 네스팅 기능을 이용, 각 컴포넌트의 최상단 html 요소 클래스 네임을 해당 컴포넌트의 이름으로 주는 것으로 각각의 컴포넌트 스타일링이 겹치지 않도록 해주었다.

예로 이런식. 이렇게 피나는 네스팅의 과정이 끝나자 징쨩이 돌아왔다.


댓글 삭제는 어떻게 하나요..

댓글 삭제하는 기능을 구현하던게 기억에 많이 남는다. 지금이야 숨쉬듯 짤 수 있지만, 그때 당시에는 핸들러 함수를 props로 던져준다는 아주 간단한 이야기를 몰랐으니까..

처음에 배운대로라면, 리액트는 정보의 흐름 방향이 위에서 아래로, 일방향이라고 하였다. 댓글에 대한 정보는 부모 컴포넌트에 있었고, 댓글 삭제 버튼을 누르는 이벤트는 자식 컴포넌트에서 발생한다. 그렇담, 자식 컴포넌트에서 발생한 이벤트의 정보를 어떻게 부모에게 전달하여 해당 댓글을 삭제시킨단 말인가. 정말 이 무슨 말도 안되는 일인가 하고 생각했다.

여러명의 동기분들을 끝없는 꼬리 질문으로 괴롭히면서 방법을 알아냈던 기억이 난다. 부모 컴포넌트에 state 값을 수정하는 핸들러 함수를 정의해주고, 해당 핸들러 함수를 자식에게 전달해준다. 이후 자식에서 해당 핸들러 함수를 호출하면 부모 컴포넌트에서 핸들러 함수가 실행되어 state 값이 변하게 되고, 이에 따른 리렌더링이 발생, 댓글이 삭제된다.

작고 귀여운 내 핸들러 함수..

프롭스로 넘겨주었고,

이벤트가 발생할 시, 넘겨 받은 핸들러 함수를 실행한다. onClick에서 바로 핸들러 함수를 넘겨주면 되는데, 그렇게 하는 방법을 몰라, 새로운 함수를 만들고 그 함수 안에서 핸들러 함수를 실행시키는 신개념 2중 함수 구조를 취했었다. 정말 귀여웠구나.


유니크한 id값은 어떻게 주나요..

댓글 삭제를 구현하는 과정에서 유니크한 id 값을 어떻게 주어야 하는지에 대해서 한창 논란이 있었다. 왜냐면, 중복삭제가 되는 일이 벌어졌으니까.

다들 id값으로 코멘트를 구분하였다. 그리고 그 id 값을 주는 방식으로 귀여웠던 우리 15기 사이에서 가장 많이 채택됬던 방식이, 새로운 댓글에 코멘트 정보가 담긴 배열의 길이 + 1 로 id 값을 주는 것이다.

댓글을 추가만 할때는 아무런 문제 없이 잘 작동한다. 하지만, 댓글 삭제 기능은 그렇게 만만하지 않았지. 삭제로 인해 id 중복이 일어나, 복수의 댓글이 동시에 삭제되는 일이 벌어졌다. 예로, 1 2 3 4 5 의 id를 가진 댓글 5개가 있다면, 3이 삭제되고 새로운 댓글이 추가되면 id 값은 1 2 4 5 5 로 변한다. 이 상태에서 5번에 해당하는 댓글을 삭제하면 2개가 동시에 삭제되는 것.

그 대안으로 수 많은 방법들이 제시가 되었다. Math.random을 사용하는 방법, Date를 사용하는 방법. 하지만 그 어느것도 완벽하지는 않았다. Math.random의 경우 성능에 악영향을 끼칠 수 있고 Date의 경우 ms를 기준으로 하므로, 컴퓨터의 관점에서는 너무나 느린 속도로 시간을 측정하기에 중복되는 값이 생성될 가능성이 높았다.

딱히 다른 대안이 없어 그나마 가장 유력하다고 생각했던 Date를 사용하는 방법을 채택하여 프로젝트를 계속 진행하였다. 중복의 가능성이 있다고는 하지만, 일단 내 기능은 아무 문제 없이 잘 작동하니까.

이후에 샤워를 하다 유레카의 순간을 경험한다. 해답이 떠올랐는데, 그 방법이 너무 심플하여 허탈했던 기억이 남아있다. 단순하게 배열 마지막 요소 id + 1 을 하면 되는 것 이었다. 그렇게 된다면 순서의 의미도 살려지고, 또 중복의 가능성도 사라진다.

해당 방식으로 다시 짰던 귀여웠던 내 코드. 많은 고민을 했었는데, 너무 어이없게 해결되버려서 기억에 남는다.


옆 메뉴를 어떻게 고정시키나요..

어느정도 기능구현을 다 마치고 마지막으로 스타일링을 몇가지 더 추가하는 작업을 했었다.

바로 요 메뉴.

생각보다 간단하다고 생각했다. 위치만 픽스가 되면 되니, position: fixed 와 세부 위치 조정만하면 될 줄 알았다. 응 아니야 ^-^

위 아래 스크롤에 대해서는 위치가 픽스가 되었다. 하지만, 스크린의 크기를 줄일 시, 옆 메뉴가 스크린과 함께 움직여 피드부분을 침범하는 일이 발생하였다.

당연한 일이긴 하다. fixed 포지션은 스크린을 기준으로 위치를 잡기 때문에, 스크린의 크기가 줄어든다면, 그에 따라 위치가 변경된다.

이를 해결하기 위해 구글에 검색을 많이 해보고 여러가지 webkit 들 또한 찾아보았지만, 해당 방법에 대한 이렇다할 해결법은 찾지 못하였다.

구현을 포기하고 마무리 작업을 하던 중 장현님이 해당 문제에 대해 글을 쓰신것을 보게 되었다. "fixed 된 요소를 div로 감싸보세요."

AsideKim 요소를 추가하여 한 꺼풀 더 씌웠다. 그리고 wrapperposition: fixed 를 주었다.

잘 작동한다. 스크린의 크기에 따라 같이 움직이지 않는다. 👍

fixed 요소는 left, right, top, bottom 으로 위치를 잡아주는 순간, 스크린을 기준으로 움직인다. 그렇기 때문에, 스크린을 기준으로 움직이는 것을 방지하면서 위치를 잡아주려면, left, right, top, bottom 를 사용하는 것 대신 겉에 하나의 요소를 감싼다. 그리고 해당 요소의 위치를 잡아주는 것으로 fixed 의 위치를 간접적으로 잡을 수 있다.

이것 또한 많이 고민했던 문제였는데, 생각보다 간단하게 풀려, 허탈감으로 인해 기억에 남았다.


마무으리 구현 데모

좋아요 버튼

댓글 달기 / 삭제

글 더보기 / 접기

반응형 디자인


귀여웠던 내 첫 리액트 프로젝트. 이젠 안녕!

0개의 댓글