Fetch 사용해 API를 불러와 response에서 status 200이 나오면 성공
import React, { Component } from "react";
import { Link } from "react-router-dom";
import DaumPostcode from "react-daum-postcode";
import styled from "styled-components";
import * as URL from "../../../config";
class JoinStep2 extends Component {
constructor(props) {
super(props);
this.state = {
even: true,
open: false,
id: "",
pwd: "",
pwdCheck: "",
koreanName: "",
englishName: "",
birthDate: "",
gender: "2",
cpNum: "",
pNum: "",
authOpen: false,
authRes: "",
authNum: "",
authBl: false,
zipCode: "",
realAddress: "",
detailAddress: "",
mail: "",
selectValue: "",
selectArr: [],
error: {
id: "",
idColor: "",
pwd: "",
pwdCheck: "",
koreanName: "",
englishName: "",
birthDate: "",
cpNum: "",
pNum: "",
authNum: "",
mail: ""
}
};
}
componentDidMount() {
this.selectJob();
}
componentDidUpdate(prevProps, prevState) {
if (prevState !== this.state) {
this.props.onKeyUp(this.state);
this.props.onClick(this.state);
this.props.onChange(this.state);
}
}
selectJob = async e => {
const selectFetch = await fetch(`${URL.SMS_URL}/job`, {
method: "GET"
});
const selectFetchJson = await selectFetch.json();
if (selectFetch.status === 200) {
this.setState({
selectArr: await selectFetchJson.jobDate
});
}
};
handleChange = e => {
this.setState({
gender: e.target.value
});
};
handleAuth = e => {
if (this.state.cpNum.length < 11) {
alert("휴대폰 번호를 입력하세요.");
this.setState({
authOpen: false
});
} else {
this.setState({
authOpen: true
});
fetch(`${URL.SMS_URL}/sms-auth`, {
method: "POST",
body: JSON.stringify({
mobile: this.state.cpNum
})
})
.then(res => res.json())
.then(res =>
this.setState({
authRes: res.AUTHENTICATION
})
);
}
};
hadnleAuthComplete = e => {
alert(
this.state.authNum === `${this.state.authRes}`
? "인증완료되었습니다."
: "인증실패하였으니 다시 입력해주십시오."
);
this.setState(previousState => {
return {
authBl:
previousState.authNum === `${previousState.authRes}` ? true : false
};
});
};
handleAddressClick = e => {
this.setState({
open: !this.state.open
});
};
handleAddress = data => {
this.setState({
open: !this.state.open,
zipCode: data.zonecode,
realAddress: data.roadAddress
});
};
handleSelect = e => {
this.setState({
selectValue: e.target.value
});
};
handleInput = async e => {
const target = e.target;
const name = target.name;
const error = this.state.error;
let idValidError = null;
const { pwd, pwdCheck, birthDate } = this.state;
// console.log(URL.SERVER_URL + "/dataId.json");
console.log("첫번쨰", e.target.value);
switch (name) {
case "id":
idValidError = await this.idCont(target.value);
error.id = idValidError.messeage;
error.idColor = idValidError.idColor;
break;
case "pwd":
error.pwd =
/^(?=.*[a-z])(?=.*[0-9]).{8,20}/.test(target.value) === false
? "8~20자의 영문과 숫자를 혼용하여 입력주세요."
: "";
break;
case "pwdCheck":
error.pwdCheck =
pwd === target.value
? ""
: pwd.length > 0 && "비밀번호가 일치하지 않습니다.";
break;
case "koreanName":
error.koreanName = /^[가-힣]+$/.test(target.value)
? ""
: "한글로 정확하게 입력해주세요.";
break;
case "englishName":
error.englishName = /^[a-zA-Z\\s]+$/.test(target.value)
? ""
: "영어로 정확하게 입력해주세요.";
break;
case "birthDate":
error.birthDate = /^(19[0-9][0-9]|20\\d{2})[\\/\\-](0[0-9]|1[0-2])[\\/\\-](0[1-9]|[1-2][0-9]|3[0-1])$/.test(
target.value
)
? ""
: "생년월일을 정확하게 입력해주세요.";
break;
case "cpNum":
error.cpNum =
/(01[016789])(\\d{4}|\\d{3})\\d{4}$/g.test(target.value) ||
target.value.length === 0
? ""
: "핸드폰 번호를 입력해주세요.";
break;
case "authNum":
error.authNum =
/[^0-9]/g.test(target.value) || target.value.length === 0
? "숫자를 입력해주세요."
: "";
break;
case "pNum":
error.pNum = /^0(2|3[1-3]|4[1-4]|5[1-5]|6[1-4])-?\\d{3,4}-?\\d{4}$/.test(
target.value
)
? ""
: "전화번호를 입력해주세요.";
break;
case "mail":
error.mail =
target.length < 1
? "이메일을 입력해주세요."
: /^([0-9a-zA-Z_\\.-]+)@([0-9a-zA-Z_-]+)(\\.[0-9a-zA-Z_-]+){1,2}$/.test(
target.value
)
? ""
: "이메일 형식을 다시 확인해주세요.";
break;
default:
"";
break;
}
this.setState({
[target.name]: target.value,
error
});
};
idCont = async param => {
if (param === "") {
return {
stat: false,
messeage: "아이디를 입력해주세요.",
idColor: "red"
};
} else if (/^(?=.*[a-z])(?=.*[0-9]).{8,20}/.test(param) === false) {
// $ 달러는 문자의 마지막
// ^ 꺽쇠는 문자의 시작
return {
stat: false,
messeage: "8~20자의 영문과 숫자를 혼용하여 입력해주세요.",
idColor: "red"
};
}
if (this.state.even) {
this.setState({
even: false
});
this.setState({
even: true
});
const idDuplicateCheck = await fetch(`${URL.SMS_URL}/id-verification`, {
method: "POST",
body: JSON.stringify({
account: param
})
});
return {
stat: idDuplicateCheck.ok && idDuplicateCheck.status === 400,
messeage:
idDuplicateCheck.status === 400
? " 중복된 아이디입니다."
: "사용가능한 아이디입니다.",
idColor: idDuplicateCheck.status === 400 ? "red" : "yellow"
};
}
return {
stat: false,
messeage: "잠시 기다려주십시오.",
idColor: "red"
};
};
hanldeCancel = e => {
this.props.history.push({
pathname: "/joinStep1"
});
};
render() {
const {
open,
id,
pwd,
pwdCheck,
koreanName,
englishName,
birthDate,
cpNum,
pNum,
authNum,
zipCode,
realAddress,
detailAddress,
mail,
selectValue,
selectArr,
error
} = this.state;
return (
);
}
}
export default JoinStep2;
<SectionInputBoxCont>
<SectionInputContainer>
<SectionInputTitle>멤버십 정보</SectionInputTitle>
<div>
<SectionInput
onKeyUp={e => this.handleInput(e)}
name="id"
defaultValue={id}
maxLength="20"
placeholder="아이디"
type="text"
/>
<SectionInputTextId color={error.idColor}>
{error.id}
</SectionInputTextId>
</div>
<div>
<SectionInput
defaultValue={pwd}
onKeyUp={this.handleInput}
maxLength="20"
name="pwd"
placeholder="비밀번호"
type="password"
/>
<SectionInputText>{this.state.error.pwd}</SectionInputText>
</div>
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={pwdCheck}
maxLength="20"
name="pwdCheck"
placeholder="비밀번호 확인"
type="password"
/>
<SectionInputText>{this.state.error.pwdCheck}</SectionInputText>
</div>
</SectionInputContainer>
<SectionInputContainer>
<SectionInputTitle>개인 정보</SectionInputTitle>
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={koreanName}
name="koreanName"
placeholder="성함"
type="text"
/>
<SectionInputText>{this.state.error.koreanName}</SectionInputText>
</div>
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={englishName}
name="englishName"
placeholder="성함(영문)"
type="text"
/>
<SectionInputText>{this.state.error.englishName}</SectionInputText>
</div>
<SectionInputBox_v2>
<SectionInputBox_v2_InputBox>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={birthDate}
maxLength="10"
name="birthDate"
placeholder="생년월일(YYYY-MM-DD 형식)"
type="text"
/>
<SectionInputText>{this.state.error.birthDate}</SectionInputText>
</SectionInputBox_v2_InputBox>
<SectionInputBox_v2_CheckboxBox>
<SectionInputBox_v2_Checkbox
onChange={e => this.handleChange(e)}
value={"2"}
checked={this.state.gender === "2"}
id="gender_male"
name="gender"
type="radio"
/>
<label htmlFor="gender_male">
<SectionInputBox_v2_CheckboxIcon>
checkbox
</SectionInputBox_v2_CheckboxIcon>
남자
</label>
<SectionInputBox_v2_Checkbox
onChange={e => this.handleChange(e)}
value={"1"}
checked={this.state.gender === "1"}
id="gender_female"
name="gender"
type="radio"
/>
<label htmlFor="gender_female">
<SectionInputBox_v2_CheckboxIcon>
checkbox
</SectionInputBox_v2_CheckboxIcon>
여자
</label>
</SectionInputBox_v2_CheckboxBox>
</SectionInputBox_v2>
<SectionInputBox>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={cpNum}
maxLength="11"
name="cpNum"
placeholder="휴대전화번호 11자"
type="text"
/>
<SectionInputButton type="button" onClick={this.handleAuth}>
인증
</SectionInputButton>
<SectionInputText>{this.state.error.cpNum}</SectionInputText>
</SectionInputBox>
{this.state.authOpen && (
<SectionInputBox>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={authNum}
name="authNum"
maxLength="6"
placeholder="인증번호 6자리"
type="text"
/>
<SectionInputButton
type="button"
onClick={this.hadnleAuthComplete}
>
확인
</SectionInputButton>
<SectionInputText>{this.state.error.authNum}</SectionInputText>
</SectionInputBox>
)}
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={pNum}
name="pNum"
placeholder="유선전화"
type="text"
/>
<SectionInputText>{this.state.error.pNum}</SectionInputText>
</div>
<SectionInputBox>
<SectionInput
placeholder="우편번호"
value={zipCode}
readOnly
type="text"
/>
<SectionInputButton type="button" onClick={this.handleAddressClick}>
주소 찾기
</SectionInputButton>
</SectionInputBox>
{open && (
<DaumPostcode onComplete={this.handleAddress} autoClose={true} />
)}
<div>
<SectionInput
value={realAddress}
placeholder="기본 주소"
readOnly
type="text"
/>
</div>
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={detailAddress}
name="detailAddress"
placeholder="상세 주소(선택)"
type="text"
/>
</div>
<div>
<SectionInput
onKeyUp={this.handleInput}
defaultValue={mail}
name="mail"
placeholder="이메일"
type="text"
/>
<SectionInputText>{this.state.error.mail}</SectionInputText>
</div>
<div>
<SectionSelect
name=""
id=""
onChange={this.handleSelect}
value={selectValue}
>
<option value="">직업(선택)</option>
{selectArr.map((item, idx) => {
return (
<option key={idx} value={idx + 1}>
{item.name}
</option>
);
})}
</SectionSelect>
</div>
</SectionInputContainer>
</SectionInputBoxCont>
import React, { useState, useReducer } from "react";
import { BrowserRouter as Route, withRouter, Link } from "react-router-dom";
import styled from "styled-components";
import * as URL from "../../config";
const Login = ({ location, history }) => {
function reducer(state, action) {
return {
...state,
[action.name]: action.value
};
}
const [idErrorStatus, SetIdError] = useState("");
const [pwdErrorStatus, SetPwdError] = useState("");
const [state, dispatch] = useReducer(reducer, {
id: "",
pwd: ""
});
const { id, pwd } = state;
const onChangeInput = e => {
dispatch(e.target);
};
const onClickLogin = async e => {
if (id.length === 0 && pwd.length === 0) {
console.log("a");
SetIdError("아이디를 입력해주세요.");
SetPwdError("비밀번호를 입력해주세요.");
} else {
const loginCheck = await fetch(`${URL.SMS_URL}/login`, {
method: "POST",
body: JSON.stringify({
account: state.id,
password: state.pwd
})
});
const resStatus = loginCheck.status;
const res = await loginCheck.json();
if (resStatus === 200) {
window.sessionStorage.setItem("Authorization", res.Authorization);
history.push("/");
} else {
SetIdError("");
SetPwdError(
"아이디, 비밀번호를 확인해주세요. 클럽 라한에 등록되지 않았거나 가입정보와 일치하지 않습니다."
);
}
}
};
return (
);
};
<>
<LoginWrap>
<LoginCont>
<LoginBox>
<LoginSubTitle>LOGIN</LoginSubTitle>
<LoginTitle>
클럽 라한에 오신 것을 환영합니다. 포인트 혜택 및 다양한 서비스를
<span>이용해보세요.</span>
</LoginTitle>
<LoginInputBox>
<li>
<LoginInput
onChange={onChangeInput}
name="id"
value={id}
type="text"
placeholder="아이디"
/>
<LoginError>{idErrorStatus}</LoginError>
</li>
<li>
<LoginInput
name="pwd"
value={pwd}
onChange={onChangeInput}
type="password"
placeholder="비밀번호"
/>
<LoginError>{pwdErrorStatus}</LoginError>
</li>
</LoginInputBox>
<div>
<LoginBtn onClick={onClickLogin}>Login</LoginBtn>
</div>
</LoginBox>
</LoginCont>
</LoginWrap>
</>