로그인 페이지에 이어서 회원가입 페이지도 회고하면서 코드를 살펴봐야겠다
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;