공백 프로젝트 1 : 회원가입 & 로그인

itssweetrain·2021년 4월 24일
0

project

목록 보기
4/8

팀 여백 전체 프로젝트 보기

SIGNUP & LOGIN


⚡️ FUNCTION

공백 사이트에는 아이디 중복검사나 비밀번호 확인 일치여부, 형식 일치여부 기능이 없다.

하지만 다른 사이트들을 보다보니 우리 사이트에도 적용해보면 유저들에게 더욱 친절한 서비스가 되지 않을까 생각하여 구현해보았다.

원래의 공백사이트의 회원가입 페이지

유효성 검사 기능을 넣은 내가 구현한 페이지

SINGUP

  • 아이디, 비밀번호, 핸드폰번호 정규표현식을 이용한 유효성검사
  • 백엔드 통신을 통한 아이디 중복검사
  • 모든 형식과 조건이 만족해야 회원가입 버튼활성화 & 가입 통신 완료
  • 통신 완료시 회원가입 환영페이지로 이동하고 가입유저이름이 나타나도록 구현

LOGIN

  • 아이디, 비밀번호 조건이 부합할 경우 로그인 버튼 활성화
  • access_token 을 이용해 토큰이 있을 시, 로그인 가능

💭 PART OVERVIEW & TIL

우리팀은 첫 날 각자 맡을 부분을 나눌 때 페이지별이 아닌 기능별로 난이도 상,중,하로 나누었다. (PROJECT OVERVIEW에서도 언급했지만 지금 생각해도 이 부분 참 좋았다!)

그 중 놀랍게도..! 회원가입 & 로그인 부분이 난이도 하로 분류되었고 내가 그 부분을 맡게 되었다. 나 또한 위스타그램 프로젝트에서 한 번 해보았기 때문에 쉽지 않을까 생각하여 동의했었는데 막상 디테일하게 구현하려다보니 처음부터 난항을 맞이하게 되었다.

'내가 맡은 파트 중에서 쉬운 부분인데, 이렇게 어렵다니 앞으로 남은 것들은 어떻게 해결해나가지?' 란 생각과 함께 첫 주 첫 날, 잠시 나를 멘붕에 빠뜨렸던 PART!

지금 생각해보면 다시 한 번 정리하고 내가 아직 온전히 다 흡수하지 못했구나라는 생각과 함께 많은 것을 깨달을 수 있었던 부분이라 애정이 가는 부분이다.

그 중에서 고민했던 부분이나 새로알게 된 개념, 공유하고 싶은 코드를 적어보고싶다.

1. 불필요한 state 값

state를 가공해서 이용하는 방법을 항상 생각해보자

유효성 검사만을 위한 state 값을 idValid 란 이름으로 새로 생성했는데 불필요한 state값이었다.

예를 들어,
idValid에서 정규표현식 조건이 참이면, 메세지가 value 값으로 담고 이 메세지는 state을 이용하여 그대로 출력하도록 하려 했었다.

state = {
  idValid: ''
};
ID_REGEX.test(signId) &&
this.setState({ idValid: '사용가능한 아이디입니다' });

하지만 이렇게 되면, 각각의 Id, Pw, phoneNum 모두 설정해줘야하며 state 객체에 담기는 양이 많아진다. (여기서부터 잘못됨을 느꼈다).

state가 변경되면 React는 새로 반환된 값을 이전에 렌더링된 요소와 비교해서 실제 DOM 업데이트가 필요한지 여부를 결정하고, 같지 않을 경우 DOM을 업데이트한다. 지금은 간단한 기능이지만 React가 변경된 DOM 노드만 업데이트하더라도 리렌더링하는데 많은 시간이 걸릴 것이다.

이렇게 유효성검사만을 위한 state 값으로 넣어주는 대신 다른 방법을 생각해본 결과, 기존에 있던 state을 이용하거나 다른 방식으로 state 값을 만들지 않고도 식을 세울 수 있었다.


2. 객체의 프로퍼티명 변수 사용하기

Input type 태그에 onChange 이벤트를 구현하는 경우는 굉장히 많이 쓰인다. 여러 개의 함수로 관리하던 것을 계산된 속성명을 사용해서 하나로 깔끔하게 사용할 수 있다.

state 값에 저장된 loginId와 loginPw를 setState 하는 각각의 함수 또한 같은 기능을 하는 것을 볼 수 있다.
=> 그렇다면 떠올려야할 건? 코드의 재사용화!

handleIdValue = e => {
 this.setState({ loginId : e.target.value })
 }

handlePwValue = e => {
 this.setState({ loginPw : e.target.value })
 }

Input의 속성과 계산된 속성명을 이용해보자.

계산된 속성명

먼저 MDN에 따르면,

// 계산된 속성명 (ES6)
let i = 0;
const a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

key 값을 대괄호로 묶고, value 를 지정해줄 수 있다. key 값에는 e.target.name에서 들어오는 것을 확인할 수 있었다. 해당 상태값에 저장하고 싶은 값은 e.target.value이다.

<input
 type="text"
 id="loginId"
 value={loginId}
 onChange={handleValueInput}
 placeholder="아이디"/>

<input
type="password"
id="loginPw"
value={loginPw}
onChange={handleValueInput}
placeholder="비밀번호" />

Input 에는 name이라는 attribute를 이용하여 속성을 줄 수 있다. 하지만, 다른 속성은 사용할 수 없을까? 생각하여 id 를 key 값으로 설정했는데, 이 또한 잘 작동하는 것을 볼 수 있었다.

코드가 같은 일을 하고 있는 것을 볼 때, 코드 재사용을 통해 어떻게 효율적인 코드를 재사용할 수 있는지 항상 생각하자

계산된 속성명에 대해 더 알아보자
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer

3. history.push를 이용하여 props 값 넘겨주기

회원가입 완료 후, 가입한 유저의 이름이 welcome page에 뜨도록 하고 싶었다. 이것을 백엔드로 데이터를 다시 보내서 불러오는 방법을 써야할까? 이미 유저의 이름은 회원가입 당시 저장되어있고 우리는 화면상 띄어주기만 하면 되는데 다른 방법은 없을까?

부모 자식간의 Component에서 자식 Component로 props를 넘겨주는 방식은 익숙하지만, 라우팅으로 특정 페이지로 props 값을 넘겨줄 수 있는 방법이 있을까?

withRouterHOC의 this.props.history.push 메소드를 이용하여 우리가 Routes.js에 저장했던 pathname을 써주고, 추가적으로 원하는 state 값을 쓰면 값이 전달되는 것을 볼 수 있다. 즉, 이것은 정보를 보내는 컴포넌트내의 state 값을 이용하여 값을 보낼 수 있는 방법이다.

.then(res => {
        if (res['MESSAGE'] === 'SUCCESS') {
          this.props.history.push({
            pathname: '/welcome',
            state: { name: name },
          });
        }
      });

로그인 페이지에서 또한 토큰이 있을 경우 alert 창과 localStorage에 토큰을 저장하게 하고, 바로 메인 페이지로 넘어가도록 하였다.

.then(res => {
        if (res.access_token) {
          alert('여백 0100 환영합니다');
          localStorage.setItem('access_token', res.access_token);
          this.props.history.push('/');
        }
      });

welcome page가 렌더링될 때 나오도록 console.log를 아래와 같이 차례대로 찍어보면,

이처럼 React Router 는 Route 에 명시되어 있는 컴포넌트에 라우팅 기능 뿐 아니라
history, location, match 라는 객체를 props 에 포함시켜 넘겨준다.

  • history : 페이지 이동을 위한 다양한 메서드들을 포함
  • location : 현재 url 경로에 관한 정보를 담는다
  • match : Path Parameter 에 관한 정보를 담는다

하지만 여기서 history 객체안에서도 location이 담겨져 있고 그 안에서도 state이 담겨져 있다. 내가 this.props.history로 push 했으니 this.props.history.location 으로 접근해야하는건가? 아니면 this.props.location으로 바로 접근하면 되는 것인가?

이것 또한 console.log에 찍어본 결과
(콘솔 2000번만 찍어보세요 by 성훈멘토님)

this.props나 this.props.history 나 react router에서 제공하는 객체 세 개가 나란히 담긴 것을 볼 수 있다.(동공지진....!)

공식 문서에서 확인해보니,

history 객체는 변할 수 있는 속성을 가지고 있기때문에, location props에 접근하여 값을 가져올 수 있다는 것!

마지막 줄을 보면 내가 console.log에 찍어봤던 것 처럼 location 객체는 history 객체에 또한 담겨져있는 것을 볼 수 있다. 하지만 but you shouldn't use that because it's mutable !

그래서 이러한 속성때문에 바로 location 에 접근하여, state 값을 받아올 수 있었다.

const name = this.props.location.state.name;

match 객체 속성 또한 path를 일치하는 값을 불러올 때 사용하였는데, 동적 라우팅에 대해 따로 글을 정리해봐야겠다!

react-router 공식 문서를 읽자
https://reactrouter.com/web/api/history

profile
motivation⚡️

2개의 댓글

comment-user-thumbnail
2021년 4월 26일

우와 단비님 정리 진짜 잘하셨네요! 감탄스! 👍👍

1개의 답글