Instagram Code Review

Jivyy·2020년 5월 24일
0

WECODE

목록 보기
19/20
post-thumbnail

이번주에 배운 내용들

이번 주에는 state와 props, router 를 이용하여 리액트에서 페이지를 이동하는 방법을 배우고,
fetch를 이용하여 직접 api 와 통신하는 실습을 하였다.
그리고 협업을 할 때 초기세팅을 하고, 클론하고 git 을 사용하는 방법까지 다시 한번 실습할 수 있었다.

초기 세팅하기

여러명이 함께 작업하는 것이 처음이었기 때문에 처음에는 초기셋팅에도 많은 시행착오가 있었다.
먼저는 한명이 cra 를 생성하고 router, sass 까지 설치한 뒤
각자 작업하기 편하게끔 각자의 폴더/페이지 별로 구분을 해두고(우리조는 3명이라 JIA/GH/NW 로 파일명/폴더명을 구분하였다)
Routes.js 파일에 하기와 같이 엔드포인트를 넣어 페이지 이동이 가능하게끔 셋팅해둔다.

import React from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
} from 'react-router-dom';
import Login_JIA from './Pages/JIA/Login_JIA/Login_JIA';
import Main_JIA from './Pages/JIA/Main_JIA/Main_JIA';
import SignUp_JIA from './Pages/JIA/SignUp_JIA/SignUp_JIA';
import Login_GH from './Pages/GH/Login_GH/Login_GH';
import Main_GH from './Pages/GH/Main_GH/Main_GH';
import SignUp_GH from './Pages/GH/SignUp_GH/SignUp_GH';
import Login_NW from './Pages/NW/Login_NW/Login_NW';
import Main_NW from './Pages/NW/Main_NW/Main_NW';
import SignUp_NW from './Pages/NW/SignUp_NW/SignUp_NW';



class Routes extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/" component={Login_JIA} />
          <Route exact path="/main_jia" component={Main_JIA} />
          <Route exact path="/signup_jia" component={SignUp_JIA} />
          <Route exact path="/gh" component={Login_GH} />
          <Route exact path="/main_gh" component={Main_GH} />
          <Route exact path="/signup_gh" component={SignUp_GH} />
          <Route exact path="/nw" component={Login_NW} />
          <Route exact path="/main_nw" component={Main_NW} />
          <Route exact path="/signup_nw" component={SignUp_NW} />
        </Switch>
      </Router>
    )
  }
}

export default Routes;

SCSS 적용 문제

이미지 파일도 각각 구분해서 넣어준 뒤, 경로지정을 다시 해 주어야 했었다.
(url 로 이미지 경로를 저장해 주는 것이 더 편할 것이라는 생각이 들었다)

여러명의 작업 내역을 합치는 과정에서 다른 사람의 scss 가 내 js 파일에 적용이 되는 문제가 발생했었는데,
이는 js 파일 내의 최상위 태그의 class 명이 같아서 생긴 문제였다.
이를 통해서 최상위 div 의 클래스명을 컴포넌트의 이름과 같이 하는 것이 좋다고 했던 이유를 알게 되었다
(이렇게 div className="Login-jia"를 해 주니 적절한 scss가 제대로 적용 되었다. scss 내의 클래스명도 함께 변경)

  render() {
    return (
      <div className="Login-jia">
        <main>
          <article className="bothside">
            <div className="login-page">
              <div className="left-side">
                <img src={phone} alt="phone-img" />
              </div>
              <div className="right-side">
                <div className="login-box">
                  <h1>
                    <img
                      className="insta-logo"
                      src={logo}
                      alt="instagram-logo"

가입하기 글씨를 누르면 사인업 페이지로 이동하게 하는 link는 원래 작성했던 a 태그와 동일한 역할을 한다.

<p>
  계정이 없으신가요?{" "}
	<Link to="/signup_jia" className="link-to-sign">
    가입하기
    </Link>
    </p>

처음에 위와 같이 js 파일 내에 작성만 하고 적용이 되지 않아 문제가 무엇인지 살펴 보았는데
알고보니 import 를 써주지 않아 생긴 문제였다... 다음부터는 빼먹지 말아야지

import { Link } from 'react-router-dom';

State 와 Props


class Login_JIA extends Component {
  state = {
    loginById: "",
    loginByPw: "",
    btState: true,
  };

  typeId = (e) => {
    this.setState({
      loginById: e.target.value,
    });
  };

  typePw = (e) => {
    this.setState({
      loginByPw: e.target.value,
    });
  };

//id 와 비밀번호 창에 onkeyup 이벤트가 일어날 때 key값을 지정하여 입력된 value 를 state에 담아준다.


  informationHandler = () => {
    if (
      this.state.loginById.includes("@") &&
      this.state.loginByPw.length >= 4
    ) {
      this.setState({ btState: false });
    } else {
      this.setState({ btState: true });
    }
  };

//입력된 아이디에 @가 포함되어 있고, 
//입력된 pw의 길이가 4자 이상일 경우 적용되는 클래스가 변경되면서 로그인 버튼의 색깔이 변경된다.


<div className="user-login">
      <input onChange={this.typeId} onKeyUp={this.informationHandler} className="login-by-id"
    type="text"placeholder="전화번호, 사용자 이름 또는 이메일"/>
      

      <input onChange={this.typePw} onKeyUp={this.informationHandler} className="type-password"
    type="password" placeholder="비밀번호" />
      <button className={this.state.btState ? "login-bt" : "login-bt-login"}
//삼항연산자 : true 일 경우 앞부분이 실행되고, false 일 경우 뒷부분이 실행된다.
    onClick={this.clickEvent} type="submit">로그인 </button>

fetch

fetch 함수를 사용해서 api 와 통신을 해본다.

<회원가입>


fetch("http://10.58.4.172:8000/account/signup", {
  method: "POST",
  headers: {
    'Content-Type': 'application/json',
  },
  
  //fetch 함수가 실행되면 첫번째 인자로 백엔드로부터 받은 url 주소를 넣어준다.
  //내가 작성한 내용을 서버에 전달하는 것이므로 method는 post이다. 
  //적어주지 않을 경우 default 는 get이므로 post를 할 경우에는 꼭 적어줘야 한다.
  //헤더에 들어가는 application/json 은 body가 json 형식이라는 내용이며 생략 가능하다.
  
  body: JSON.stringify({
    'email' : this.state.SignUpEmail,
    'name' : this.state.SignUpName,
    'nick_name' : this.state.SignUpNick,
    'password' : this.state.SignUpPw
  })
})

//body에 들어가는 JSON/stringify는 아래의 내용들을 json 형식으로 변환하겠다는 의미이며
//백엔드 쪽과 맞추어놓은 key 와 state에 저장된 value 값을 넘겨준다.

  .then(response => response.json())
//응답이 오면 json 형태로 온 응답을 js형태로 변환하겠다는 의미
//이 부분에 console.log를 넣어 확인하게 되면 다음에 오는 코드들이 실행이 멈춰버리므로 주의한다.
  .then(response =>  
        {if (response.message=="SUCCESS") {
          alert("회원가입에 성공하였습니다 로그인을 해주세요");
          //resopnese의 message 키의 값이 백엔드가 정해놓은 대로 success일 경우, 메인 로그인 페이지로 이동한다.
          //만약 resopnse.status==200이나 reponse.ok 과 같이 코드값으로 확인하고 싶은 경우에는
          //response를 js 형태로 변환하지 않고 json형태에서 바로 실행해야 한다.
          this.props.history.push("/");
        } else {
          alert("중복된 회원정보가 있습니다.");
          this.props.history.push("/signup_jia")
          //아닐 경우, 알림창을 띄워주고 회원가입 창을 리로드 한다.
        }
        }
       )

<로그인>

  clickEvent = () => {
    console.log(this.state.loginById);
    console.log(this.state.loginBy);

    fetch("http://10.58.7.154:8000/accounts/signin", {
      method: "POST",
      headers: {
        'Content-Type': 'application/json',
    },
      
      //fetch 함수의 첫번째 인자로 통신할 주소를 백엔드로부터 받아서 넣는다.
      //마찬가지로 정보를 서버에 보내는 것이므로 post method를 사용한다.
      
      body: JSON.stringify({
        'email': this.state.loginById,
        'password': this.state.loginByPw,
      })
    })
      .then(response => response.json())
      .then(response => {
      //로그인의 경우 서버쪽에 저장된 회원아이디/비밀번호가 일치할 경우 서버에서 토큰을 발행하여 보내주게 된다.
        if (response.token) {
          console.log(response);
          localStorage.setItem("wtw-token", response.token);
        //토큰이 오는 경우 로컬스토리지에 토큰을 저장하게 되는데 앞부분은 임의로 지정한 토큰의 키 값이다.
          this.props.history.push("/main_jia");
          //토큰을 저장한 후 메인페이지로 이동하게 된다.
        } else if (!response.token) {
          alert("올바른 회원이 아닙니다");
          this.props.history.push("/signup_jia");
          //토큰이 오지않는 경우=회원정보가 다른 경우 이므로 알림을 띄워주고 회원가입창으로 이동한다.
        }
      });
  };

추가로 Git

npm install

이번 주에는 처음으로 git 과 github를 자주 사용할 수 밖에 없게 되었는데, 그동안 막연하게 두렵게 생각했던 git과 조금 더 친숙해 질 수 있었던 좋은 기회였다.
먼저는 git clone을 한 후에 보니 gitignore 때문에 node_modules 파일이 없어 이를 강제로 옮기는 시행착오를 겪었는데
알고보니 git clone을 한 뒤, npm install 을 해 주면 node modules 와 필요한 패키지들까지 쉽게 설치가 된다는 것을 알고 허탈해졌다..
다음부터는 무조건 git clone 뒤에는 npm install

git add -p

그리고 같은 조원의 크롬에 문제가 있어 내 크롬에서 확인을 해 보느라, 다른분의 작업중인 js 파일을 건드리게 되었는데
나중에 git push를 하려고 보니 conflict 가 나면 어쩌나 하는 걱정이 되어 구글링을 해보니 git add -p라는 아주 편리한 기능이 있었다.
git add .처럼 모두 add 를 하기에 위험성이 있을 때 git add -p 를 해주면 그동안 modified 한 내용들을 하나하나 확인해 보면서 add 할지말지를 결정할 수 있다.
그래서 내 파일들만 안전하게 push 할 수 있었다.

Pull Request 와 Commit message

계속해서 commit 메세지 작성과 pull request 템플릿 작성을 구체적으로, 성의껏 할 것을 강조하셨는데
귀찮게 여겨질 수도 있지만 나만을 위해서가 아니라 다른 사람이 알아보기 쉽도록 작성할 수 있는 습관을 들이는 것이 중요할 것 같다.

마치며

어렵게 생각했던 기능들을 직접 구현해 보고 초기세팅과 git과 조금 더 친해진 것에 대해 개인적으로 큰 의미를 두고 싶었다.
실제로 api 와 통신해서 토큰이 콘솔에 찍히는 것을 보고 백엔드 조원분과 이게 정말 된다며 뿌듯함을 느꼈던 순간을 잊지 못할 것 같다.

profile
나만의 속도로

0개의 댓글