1차 프로젝트 회고 (회원가입 페이지)

로그인 페이지에 이어서 회원가입 페이지도 회고하면서 코드를 살펴봐야겠다


map 메소드를 사용하기 위한 상수데이터

const INPUT_LIST = [
  {
    id: 1,
    className: 'inputId',
    inputType: 'text',
    name: 'id',
    placeholder: '아이디 (4자 이상, 영문)',
    maxLength: '10',
    errormessage: '영문으로 4자 이상 입력하세요',
  },

  {
    id: 2,
    className: 'inputPw',
    inputType: 'password',
    name: 'password',
    placeholder: '비밀번호 (8자 이상, 영문, 숫자, 특수문자)',
    maxLength: '15',
    errormessage: '영문, 숫자와 특수문자를 넣어서 8자 이상 넣어주세요',
  },

  {
    id: 3,
    className: 'inputEmail',
    inputType: 'text',
    name: 'email',
    placeholder: '이메일 주소',
    errormessage: "@와 '.' 을 포함해서 작성해주세요",
  },

  {
    id: 4,
    className: 'inputName',
    inputType: 'text',
    name: 'userName',
    placeholder: '이름',
  },
];

export default INPUT_LIST;

회원가입 부모 컴포넌트 페이지

import React, { Component } from 'react';
import UserNav from '../../components/userNav/userNav';
import InputData from './InputData';
import INPUT_LIST from './inputList';
import './SignUp.scss';

// 리액트 컴포넌트를 사용하기 위한 import와 자식컴포넌트인 InputData, map 함수를 써서 불러올 상수데이터 INPUT_LIST 를 import 한다

export class SignUp extends Component {
  constructor() {
    super();
    this.state = {
      id: '',
      password: '',
      email: '',
      userName: '',
      birth: '',
      gender: '',
    };
  }

  // 초기값으로 id, password, email, userName, birth, gender 를 만들어주고 공백을 value로 할당해준다

  submitUserInfoToSignUp = e => {
    const { id, password, userName, email, birth, gender } = this.state;
    fetch('http://10.58.7.203:8000/users/signup', {
      method: 'POST',
      body: JSON.stringify({
        id: id,
        name: userName,
        password: password,
        email: email,
        yearOfBirth: birth,
        gender: gender,
      }),
    })
      // fetch 함수로 state 값을 백엔드 서버에 전달한다 이때 key 값은 백엔드에서 설정한 값과 동일하게 해준다

      .then(response => response.json())
      .then(data => {
        if (data.message === 'Id format is not valid') {
          alert('유효하지않은 아이디입니다.');
        } else if (data.message === 'Password_Validation_Error') {
          alert('유효하지 않은 비밀번호입니다.');
        } else if (data.message === 'Email format is not valid') {
          alert('유효하지 않은 이메일입니다.');
        } else if (data.message === 'ID_Exist_Error') {
          alert('이미 등록된 아이디입니다.');
        } else if (data.message === 'Email.Exist_Error') {
          alert('이미 등록된 이메일입니다.');
        } else if (data.message === 'SUCCESS') {
          alert('회원가입 성공');
          this.props.history.push('/Login');
        }
      });
  };

  // 백엔드에서 설정한 에러메세지로 조건을 걸어 각 에러마다 해당하는 alert 창을 띄워주고
  // 메세지가 'SUCCESS' 일때 성공 alert 창을 띄워주고 props로 넘겨받은 history 객체로 '/Login' 경로로 이동한다

  handleInputs = e => {
    const { name, value } = e.target;

    this.setState({
      [name]: value,
    });
  };

  // name, value를 e.target 으로 구조분해할당해주고 name 값에 따라서 value 값에 접근한다음 setState로 값을 업데이트 한다

  pushGender = e => {
    const { name } = e.target;
    this.setState({
      gender: name === 'male' ? 1 : 2,
    });
  };

  //  name 를 e.target 으로 구조분해할당해주고 삼항연산자를 이용해 state 의 gender의 name 값이 'male'이면 1 을 setState로 업데이트해주고
  // male 이 아닐경우 2 로 setState 업데이트 해준다

  render() {
    const { pwCheck, password } = this.state;

    // pwCheck, password 를 this.state 로 구조분해할당해준다

    return (
      <div className="totalContainerSignUp">
        <div className="signUpBody">
          <section className="signUpSection">
            {INPUT_LIST.map(inputList => {
              return (
                <InputData
                  key={inputList.id}
                  inputList={inputList}
                  handleInputs={this.handleInputs}
                />
                // map 메서드로 상수데이터를 새로운 배열인 inputList에 하나씩 넣고
                // 자식 컴포넌트인 InputData 에 key, 상수데이터 inputList 를 props 로 넘겨주고 handleInputs 함수도 넘겨준다
              );
            })}
            <p className="choosePtag">선택 입력</p>
            <div className="birthYearSex">
              <input
                className="inputBirthYear"
                type="text"
                name="birth"
                placeholder="출생년도"
                onChange={this.handleInputs}
              />
              <span className="MenWomen">
                <button
                  name="male"
                  onClick={this.pushGender}
                  className="buttonMaleFemale"
                ></button>
                <button
                  name="female"
                  onClick={this.pushGender}
                  className="buttonMaleFemale"
                ></button>
              </span>
            </div>
            <button
              onClick={this.submitUserInfoToSignUp}
              className="signInbutton"
            >
              회원 가입 완료
            </button>
          </section>
        </div>
      </div>
    );
  }
}

export default SignUp;

회원가입 페이지 자식 컴포넌트

import React, { Component } from 'react';

export class InputData extends Component {
  constructor() {
    super();
    this.state = {
      isValid: false,
    };
  }
  
// 유효성 검사를 위한 초기 상태값 isValid를 false로 설정한다
  
  handleInputs = event => {
    const { handleInputs } = this.props;
    const { name } = this.props.inputList;
    handleInputs(event);

    
 // 부모 컴포넌트에서 물려받은 handelInputs 함수를 사용하여 name 값에 따라서 value 값에 접근한다음
 // setState로 값을 업데이트 한다 ( onChange 이벤트로 자식 컴포넌트의 handleInputs 함수를 실행시켜 부모 컴포넌트로 값을 전달한다 )

    
    if (name === 'id') {
      const idReg = /^[A-Za-z]{1}[A-Za-z0-9]{3,}$/;
      idReg.test(event.target.value)
        ? this.setState({ isValid: true })
        : this.setState({ isValid: false });
    } else if (name === 'password') {
      const pwReg = /^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*-+_=?]).{8,}$/;
      pwReg.test(event.target.value)
        ? this.setState({ isValid: true })
        : this.setState({ isValid: false });
    } else if (name === 'email') {
      const pwReg =
        /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;
      pwReg.test(event.target.value)
        ? this.setState({ isValid: true })
        : this.setState({ isValid: false });
    }
  };

// if 조건식으로 name 이 id 라면 아이디 input창에 대한 정규식 유효성검사를 하고
// name 이 password 라면 비밀번호 input창에 대한 정규식 유효성검사를 하고
// name 이 email 이라면 이메일 input창에 대한 정규식 유효성검사를 하고
//.test() 로 event.target.value의 true or false 값을 setState로 isValid 의 상태값을 업데이트한다

  render() {
    const { inputList } = this.props;
    const { inputType, placeholder, name, maxlength, errormessage } = inputList;

    return (
      <div>
        <input
          name={name}
          className="inputData"
          type={inputType}
          placeholder={placeholder}
          maxlength={maxlength}
          onChange={this.handleInputs}
        />
        {!this.state.isValid && (
          <span className="errorMessage">{errormessage}</span>
        )}
      </div>
    );
  }
}

// map메서드로 저장된 inputList 배열의 인덱스인 키 값들을 id 값의 순서대로 리턴(렌더링) 한다

export default InputData;

시현 영상 : https://www.youtube.com/watch?v=lOiYYq0XvAc

좋은 웹페이지 즐겨찾기