Instagram Clone Review

Minji Jeong·2021년 10월 3일
0

Project

목록 보기
1/3
post-thumbnail

2주간 Instagram 로그인 페이지와 메인 페이지를 클론코딩 해보았다.
먼저, 어떤 기능들을 구현했는지 간단하게 정리해보자.

로그인 페이지

유효성 검사


id에 @가 포함되고, pw가 5글자 이상인 유효성 검사를 통과하면 로그인 되어
메인 페이지로 넘어가는 기능이다.
처음에는 id의 value를 가져오는 함수와, pw의 value를 가져오는 함수를 분리하여 각 input에 onChange 리스너를 부여했는데, e.target.name으로 input의 name값을 가져와서 하나의 함수로 합칠 수 있었다.
이 때, input의 name값과 state의 값이 동일해야 한다.

유효성 검사에 따른 버튼 색상 변경

const isBtnEnabled =
      this.state.idValue.includes('@') && this.state.pwValue.length >= 5;

해당 코드가 true값이냐, false 값이냐에 따라서 버튼의 className을 바뀌도록
하고, className에 따라 다른 css를 주어 색상이 변경되도록 하였다.

메인 페이지

댓글 추가

처음에는 this.state.commentList에 바로 새로운 객체를 push하여 댓글을 추가하는 방식을 사용하였다. 하지만 React에서는 불변성 유지 때문에 직접적으로 state 값을 수정해서는 안된다.
불변성을 유지해야 데이터들이 업데이트 되어야 하는 상황에 리렌더링 되도록 할 수 있다. 즉, state의 값을 변경하고 싶으면 push를 통해 그 값을 직접 변경하는 것 보다는 새로운 변수에 추가할 객체를 선언하고, this.setState 안에서 state값에 변수를 대입하는 방식으로 수정해주어야 한다는 것이다.
그래야 this.setState가 불리는 시점에서 render 함수가 다시 불려지고, 정상적으로 state값을 변경할 수 있다.

댓글 삭제

댓글 삭제 부분도 추가 부분과 비슷한 로직이다.
filter 함수를 사용하여, 현재 commentList에서 사용자가 삭제 버튼을 누른 comment의 id값과 같은 comment를 찾아, 그 comment는 제외한 나머지 배열로 새로운 commentList를 만드는 방식이다.

댓글 좋아요

우선, 사용자가 하트를 눌렀을 때 commentList의 isLiked값을 수정하려면
spread 연산자를 사용하여, 나머지 속성들은 그대로 대입하고 isLiked 값만 수정해서 넣어주면 된다. 따라서 commentList에서 사용자가 하트 버튼을 누른 댓글과 같은 id값을 가지고 있는 댓글을 찾아, isLiked 속성에 !isLiked를 대입해준다.

프로필 버튼 클릭 시, menuBox show/hide


버튼을 클릭할 때 마다 isVisible 함수의 true/false 값을 토글 시켜주고,
그에 따라서 메뉴박스의 class를 변경하여 .show_menu 일 때 display: block, .hide_menu 일 때 display: hidden 속성을 주었다.

아이디 검색


먼저, Mock Data에 저장된 인스타그램 UserList를 fetch함수를 통해 가져온다.
유저가 input에 검색하고자 하는 단어를 입력하면, userList에서 filter 함수를 이용하여 해당 단어를 포함하고 있는 userId 리스트를 filtered라는 변수에 저장한다.

그 뒤 this.state.filteredList에 필터된 리스트가 들어있는 변수를 넣어준다. 사용자가 아무 값도 입력하지 않았을 때는 아무것도 필터링 되지 않아 전체 아이디를 모두 보여주게 된다. 하지만 아무 값도 입력하지 않았을 때는 아무 것도 보여지지 않게 하기 위해서, this.state.userList.lengthfiltered된 리스트의 length와 같은 경우에는 배열을 비워버리는 조건식을 넣어주었다.

Array.map()

반복되는 엘리먼트를 찍어주는 부분(피드, 댓글, 스토리, 친구추천, 필터링 된 아이디 등)은 Array.map()을 사용하였다.
map을 이용해서 반복된 엘리먼트를 찍어주는 경우에는, React가 list의 순서를 인지할 수 있도록 하기 위해 반드시 key={id}처럼 key값을 넘겨주어야 한다.
위처럼 자식 컴포넌트로 부모 컴포넌트의 state값을 넘겨주게 되면, 자식 컴포넌트에서 this.state.props 값으로 부모가 보낸 데이터를 받아 엘리먼트를 생성하게 된다.

Code Refactoring

구조분해할당

this.state, this.props, list.~ 처럼 같은 코드가 반복될 경우에는 구조분해할당을 사용할 수 있다.

const {id, userId, content, isLiked} = this.props;

이렇게 위에서 선언을 하면, 아래에서 변수를 사용할 때는 this.props.userId가 아닌 userId로 줄여서 사용할 수 있다.

Sass Nesting

Sass에서 nesting을 사용하는 이유는 SPA를 만들 때 각 엘리먼트의 css 속성이 서로에게 영향을 미치지 않도록 부모를 확실하게 지정해주기 위해서이다.

처음으로 Sass를 사용하다보니, 그 특성을 잘 이해하지 못해서 nesting이 필요한 부분 곳곳에 nesting이 빠져있는 경우도 많았고, className을 지정해주지 않은 곳도 있었다. 지금은 페이지가 두 개 밖에 없기 때문에 인지하지 못한 것 같지만, 나중에 페이지가 여러개이고 반복되는 엘리먼트가 많아지면 css가 겹치면서 깨지는 현상이 일어날 것이다.

인라인 함수 지양

엘리먼트에 함수를 부여할 때, onClick={() => handleToggle()} 처럼 인라인으로 함수를 주는 경우가 많다. 하지만 한번 생각해보자.
엘리먼트들은 render() 함수가 실행되면서 불려온다. 따라서 인라인으로 함수를 주게 되면 state 값이 바뀌어서 render()가 실행될 때마다 함수를 생성하게 되므로 비효율적이다.
따라서 위의 코드처럼 컴포넌트의 render() 바깥에서 함수를 불러오는 함수를 따로 선언하여 함수를 받아오고,onClick={thishandleRemoveComment} 처럼 엘리먼트 내에서는 본인 컴포넌트의 함수를 부르는 식으로 표현하면 더 효율적일 것이다.

마무리

React state, props도 이해 못하고, 자바스크립트로 기능 구현도 잘 못했던 내가
이번 클론 코딩을 통해 꽤 많이 발전한 것 같다. state와 props를 이해하게 되면서 기능을 구현할 때, 어떤 흐름으로 구현해야 할지 흐름을 머릿속에 그릴 수 있게 되었다. 처음에 기능 구현에 초점을 맞추다 보니 변수명, 효율성, 가독성 등에 신경을 못 쓴 부분들이 많아 Code Refactoring을 통해 하나씩 수정해 나갔다.

내가 사용하는 기술(React, Sass 등)을 왜 쓰는가?에 초점을 맞추면 그 기술의 본질에 대해서 생각하게 되고, 그러다 보면 코드 하나하나를 작성할 때 어떻게 구현해야 더 효율적이고, 본질에 어긋나지 않는지 계속 고민하게 되는 것 같다.

가장 중요한 것은 클론 코딩을 하는 2주 동안 너무 재밌었다는 것이다.
물론 코드를 짜다가 막히거나, 컴포넌트를 분리하다가 꼬이기 시작하면 머리가 지끈거리긴 했지만, 초기에 프로젝트를 구성하는 방법, 데이터가 전달되는 방법, 서버와 통신하는 방법, Git 사용 방법까지 많은 것을 배우고 내 것을 만들 수 있어 정말 뿌듯했다. 다음 프로젝트가 정말 기대된다 😀

profile
쿼카를 사랑하는 프론트엔드 개발자입니다 :)

0개의 댓글