Project | 인스타그램 클론 코딩 리뷰 (1)

Ryan·2020년 11월 12일
5

Project | Westagram

목록 보기
1/3
post-thumbnail

인스타그램을 만들어보자.
피드를 올릴수는 없지만 다양한 피드가 존재하고 여러 계정으로 로그인이 가능하고 로그인 한 계정으로 댓글을 쓰고 지우고 좋아요까지 할 수 있는 진짜 인스타 같은 인스타를 만들어보자.

1. 왜 클론을 하는가?

: 실제 구현되어있는 서비스를 직접 내 손으로 한땀 한땀 연구해서 만들어가는 것만큼 빠르고 효과적인 공부 방법은 없다. 다른 의도는 없으니 저작권으로 잡아가지마세열
한개의 기능을 3일간 고민해서 만들어보기도 했고, 왜 안되는지 콘솔을 수백번 찍어보기도 했다.
내가 짠 코드를 내가 읽지 못하던 모습에서 차츰 쉽게 코드를 이해하는 모습으로 바뀌어 가는 것을 볼 수 있었다.


2. 나만의 목표

: 이번 프로젝트는 프론트만 구현하는 것이기 때문에 뷰만 하드코딩 하면 되었고... 로그인 기능 또한 조건문만으로 로그인을 구현하는 것이 학습 프로젝트였지만 개인적으로 조금 더 욕심을 부려보기로 했다.

  • 서버가 있다고 가정하고 다양한 계정들로 로그인 되는 기능을 만들어보고 싶었다.
  • 또한 내가 로그인한 계정으로 계정 정보가 바뀌게 해보고 싶었다.
  • 구글링을 해보니 서버에서 json 파일의 형태가 어떻게 넘어오는지 알 수 있었고.... 그렇다면 그 형태의 데이터를 내 로컬에 미리 만들어두면 내 맥북이 서버가 되지 않을까?? 라는 생각에서 나만의 개인 목표가 한개 추가되었다.

3. 클론 기간 및 학습순서

: 단계적으로 학습을 하고 있기 때문에 내가 배운 기술 범위 내에서 직접 하나 하나 구현해본다.
예를 들면 HTTP, CSS를 배웠을때는 그것만을 이용해서 하드 코딩으로 완전한 인스타그램을 구현해보고
React를 배운 이후에는 하드코딩 해서 만들었던 페이지를 React로 전환해보는 방식이다.
처음엔 다짜고짜 레이아웃 나누면서 Project Start!

1) 날짜 및 기간

  • 날짜 : 2020. 11. 2 - 2020.11. 12
  • 기간 : 10일

2) 학습 순서

  • 1단계: HTMLCSS로 보여지는 페이지의 레이아웃과 스타일을 구현한다.
  • 2단계: 자바스크립트DOM을 이용하여 다양한 기능을 구현한다.
  • 3단계: HTML 하드코딩 된 코드를 React를 이용해서 컴포넌트 단위로 분리시킨다.
  • 4단계: CSS를 SCSS로 네스팅 시키고 Reset.scss 와 Common.scss 로 공통 스타일을 분리시킨다.
  • 5단계: React를 이용해서 DOM으로 구현했던 기능들을 재구현해본다.

4. 무엇을 사용했는가?

  • Development environment: CRA(Creat-React-App)
  • Language: JavaScript
  • Library: React
  • Third-party Library: React Router, Axios
  • Style: SCSS

5. Code Review

: 싱크로율을 100%로 맞춰보았다. 기능에 초점을 두어야하지만...
예쁘지 않으면 더 욕심이 생기지 않을 것 같아서 집착을 부려보았다.
(인스타도 완벽하진 않더라... 스토리 부분과 피드 부분이 딱 1픽셀 정렬이 안되어 있더라)

1) Login Component 주요 코드

(1) 계정 정보 관리

: 뒤에 알게된 사실인데... 위에서 설명한 나만의 목표가....
목업 데이터로 작업하는 경우 그렇게도 한다고 하더라.
아무튼... 일단 디즈니 캐릭터 10명을 강제로 가입시켜보자.

// account.json : 목업 데이터
{
  "accountList": [
    {
      "id": "0",
      "group": "myProfile",
      "account": "Disney_World",
      "introduce": "The Walt Disney Company",
      "passWord": 1111,
      "profileImage": "/images/SangHyukAhn/myprofile/profile.png"
    },
     {
      "id": "1",
      "group": "follow",
      "account": "Moana",
      "introduce": "Moana of Motunui",
      "passWord": 123123,
      "profileImage": "/images/SangHyukAhn/friends/friend2.png"
     },
    ....... // 생략
  ]
}
// Login.js : Axios로 서버에서 데이터 받아오기
  getAccountInfo = () => {
    axios.get('/data/SangHyukAhn/accountInfo.json').then((element) => {
      this.setState({ accountInfo: element.data.accountList });
    });
  };
  • API주소가 입력되는 곳에 내 로컬 주소를 넣어 목업 데이터를 서버처럼 사용해봤다.
    (이때 되는 것을 확인하고 너무너무 기분 좋았던 기억이 떠오른다.)
  • accountInfo 라는 state에 받아온 정보를 담아 활용했다.
  • state은 변수와 닮아 보이지만 setState 라는 함수로만 수정이 가능하다.

(2) 로그인 입력(input) 및 버튼 이벤트

// Login.js : 로그인 정보 입력 이벤트
  handleInputValueChange = (e) => {
    const { id, value } = e.target;
    this.setState({ [id]: value });
  };
  // render 부분
  <input
    id='id'
    type='text'
    className='inputId'
    placeholder='아이디를 입력하세요.'
    onChange={handleInputValueChange}
  />
  • state에 id를 만들어 input을 통해 들어온 정보를 넘겨주었다.
  • 넘어온 정보는 아래 버튼 이벤트를 통해 조건이 맞는 경우 로그인이 가능하게 하였다.
// Login.js : 로그인 버튼 이벤트
  handleViewChage = (e) => {
    e.preventDefault();
    const loginName = this.state.id;
    const { id, accountInfo, password } = this.state; // 구조 분해 할당
    for (let i = 0; i < accountInfo.length; i++) {
      let checkId = accountInfo[i].account === id;
      let checkPw = accountInfo[i].passWord === password - 0;
      if (checkId && checkPw) {
        this.setState({ errorMsg: '로그인 성공!!' });
        this.props.history.push('./main', {
          name: loginName,
          passWord: '',
          profileImage: '',
        });
        break;
      } else if (checkId && !checkPw) {
        this.setState({ errorMsg: '비밀번호를 정확히 입력하세요.' });
        break;
      } else {
        this.setState({
          errorMsg: '아이디 또는 비밀번호를 정확히 입력하세요.',
        });
      }
    }
  };
  // render 부분
  <button
    type='button'
    className={id && password ? 'loginButton' : 'hiddenButton'}
    onClick={handleViewChage}>로그인
  </button>
  • e.preventDefault() : 기본적으로 form에서 onSubmit()을 통해 submit 하면 이벤트 완료 후 refresh가 된다. 하지만 리액트로 만드는 SPA앱에서는 이것을 원하지 않는다.
    그래서 event.preventDefault() 를 활용하여 추가로 이벤트를 전파하지 않고 취소할 수 있다.
  • this.props.history.push : 로그인 성공시 Router를 이용해서 다른 경로로 보내준다. 여기서 중요한 것은 나의 개인 목표인 로그인을 함과 동시에 로그인한 개인 정보를 메인으로 넘겨주는 부분이다. 이때까지는 토큰을 활용하거나 로컬에 계정 정보를 저장하는 것은 배우지 않았을때라 이 방법을 사용했었다.
  • className 에 조건문을 사용하여 id, password를 1개의 값이라도 입력하지 않으면 버튼 스타일이 다르게 보여지도록 만들었다.

(3) 비밀번호 보이게/감추게 하기 버튼

// Login.js : password 감추기/보이기 이벤트
  hidePassword = (e) => {
    this.setState({ hiddenPw: !this.state.hiddenPw });
  };
  // render 부분
  <div class='inputPwBox'>
     <input
    	id='password'
    	type={hiddenPw === true ? 'text' : 'password'}
    	className='inputPw'
    	placeholder='비밀번호를 입력하세요.'
    	onChange={handleInputValueChange} />
     <button className='hideButton' onClick={hidePassword}>
    	{hiddenPw ? 'Show' : 'Hide'}
     </button>
  </div>
  • state에 hiddenPw: false 를 미리 두어 스위치 기능을 만들어둔다.
  • 버튼을 onClick 시 해당 함수가 실행되면 true, false 값에 따라 input바의 type이 달라진다.
  • 또한 innerText 까지 show 또는 hide 로 전환된다.

to be continue.... Main 페이지 리뷰는 여기서 계속

profile
"꾸준한 삽질과 우연한 성공"

0개의 댓글