실제 마켓컬리 사용자 정보 검증
여러 입력 정보 중 fake api의 user 등록 request body와 맞춰서 어떤 정보까지 받을 지 결정해야함
사용자 입력 정보 목표
아이디, 비밀번호, 비밀번호 확인, 이름, 이메일, 휴대폰, 주소, 성별, 생년월일
실제 마켓 컬리 사용자 정보 검증 목표
마켓컬리는 입력칸을 누르면 아이디, 비밀번호, 비밀번호확인의 조건이 나온다. 그리고 사용자 입력에 따라 그 조건 충족 여부를 빨간색(불충족), 초록색(충족)으로 보여줌
사용자 입력 정보 검증 목표
단계 (1) 사용자 입력칸 클릭 시 조건 보이도록 함
단계 (2) 코딩차원에서 조건 충족 여부 확인
단계 (3) 조건 충족 여부에 따라 색깔 표현
실제 마켓 컬리 사용자 주소 입력
단순히 주소를 text로 입력 받지 않고 Postcode API - Daum
사용해 우편번호와 정확한 주소를 받아온다.
![]() | ![]() |
받은 우편 번호와 주소에 상세 주소를 입력함.
샛별배송 가능 여부를 보여줌. 새롭게 주소를 설정하고 싶은 경우 주소 입력 버튼이 재검색으로 바뀜
사용자 주소 입력 목표
실제 마켓 컬리 사용자 성별 입력
성별은 남자, 여자, 선택 안함 3가지 선택이 있고 3가지 중 한개는 필수적으로 선택되어야 함
fake-store api에서 유저 등록하는 POST API를 사용
하나의 값으로 한 개의 useState만 관리 가능하지만 회원가입에 필요한 모든 값을 매번 useState로 관리하기 어려움
const [inputs, setInputs] = useState({
Id: "",
showIdInfo: false,
Pwd: "",
showPwdInfo: false,
RePwd: "",
showRePwdInfo: false,
Username: "",
Phone: "",
Email: "",
showAddressPop: false,
Address: "",
Bname: "",
BuildingName: "",
FullAddress: "",
ExtraAddress: "",
ZoneCode: "",
Sex: 1,
BirthDate: "",
});
const {
Id, //
showIdInfo,
Pwd, //
showPwdInfo,
RePwd,
showRePwdInfo,
Username, //firstname, lastname
Phone, //
Email, //
showAddressPop,
Address,
Bname,
BuildingName,
FullAddress,
ExtraAddress,
ZoneCode,
Sex,
BirthDate,
} = inputs;
html input 태그에 사용자의 입력값을 받는 input 태그
<input
className="signup_Pw_input"
name="Pwd"
placeholder="비밀번호를 입력해주세요"
maxLength="16"
type="text"
onChange={onChange}
value={Pwd}
onClick={onClick_Info}
/>
change 이벤트가 발생한 경우 다음의 함수를 실행함
입력한 input 태그의 name과 value 속성을 사용해 값을 setInputs
이용해 설정함
...inputs
를 통해 변화가 발생한 것이 아닌 것들은 그래도 값을 유지하고 event가 발생한 input 태그의 name, value 속성을 사용해 값을 변경해줌
const onChange = (e) => {
const { value, name } = e.target;
setInputs({
...inputs,
[name]: value,
});
console.log(inputs);
};
input type="radio" 이용
<div className="signup_Sex_title">성별</div>
<div className="signup_Sex_block" onClick={onChange}>
<label>
<input type="radio" name="Sex" value="1" defaultChecked />
남자
</label>
<label>
<input type="radio" name="Sex" value="2" />
여자
</label>
<label>
<input type="radio" name="Sex" value="0" />
선택 안함
</label>
</div>
defaultChecked
속성을 이용해 처음 회원가입페이지가 랜더링되었을 때 어느 것이 선택되어햐 하는 지 지정했음
각 <input>
에 value
속성을 부여하여 API POST 요청으로 넘길 SEX
카테고리 값으로 연결했음
다음 우편주소 npm 이용을 참고함
다음 우편주소 npm을 설치하고 DaumPostcode
이용한 컴포넌트로 작성하고
getData
props를 이용해 받은 주소 정보를 콘솔확인하고 setInputs로 POST 요청에 필요한 값들(Address, Bname, BuildingName, FullAddress, ZoneCode, showAddressPop)을 세팅함
<div className="signup_Address_block">
{showAddressPop ? (
<Post
getData={(
address,
bname,
buildingName,
fullAddress,
zoneCode
) => {
console.log(
address,
bname,
buildingName,
fullAddress,
zoneCode
);
setInputs({
...inputs,
Address: address,
Bname: bname,
BuildingName: buildingName,
FullAddress: fullAddress,
ZoneCode: zoneCode,
showAddressPop: false,
//핸드폰번호 text아닌 숫자로 입력될까봐...
});
}}
/>
import React from "react";
import DaumPostcode from "react-daum-postcode";
const Post = ({ getData }) => {
const handleComplete = (data) => {
let fullAddress = data.address;
let extraAddress = "";
if (data.addressType === "R") {
if (data.bname !== "") {
console.log("✔ post 컴포넌트 bname : ", data.bname); //신갈동
extraAddress += data.bname;
}
if (data.buildingName !== "") {
console.log("✔ post 컴포넌트 buildingName : ", data.buildingName); //녹원마을새천년그린빌1단지아파트
extraAddress +=
extraAddress !== "" ? `, ${data.buildingName}` : data.buildingName;
}
fullAddress += extraAddress !== "" ? ` (${extraAddress})` : "";
console.log("✔ post 컴포넌트 extraAddress : ", extraAddress); //신갈동, 녹원마을새천년그린빌1단지아파트
console.log("✔ post 컴포넌트 address : ", data.address); //경기 용인시 기흥구 새천년로 13
}
console.log("✔ post 컴포넌트 zonecode : ", data.zonecode); //16958
console.log("✔ post 컴포넌트 fullAddress : ", fullAddress);
getData(
data.address,
data.bname,
data.buildingName,
fullAddress,
data.zonecode
);
};
const postCodeStyle = {
display: "block",
position: "absolute",
top: "20%",
width: "400px",
height: "400px",
padding: "7px",
zIndex: 100,
};
return (
<>
<DaumPostcode
style={postCodeStyle}
autoClose
onComplete={handleComplete}
/>
</>
);
};
export default Post;
getData={(address,bname,buildingName, fullAddress, zoneCode) =>....
로 작성했고
const Post = ({ getData }) =>
{}를 이용해서 props를 받왔기 때문에 별도의 key:value
매칭으로 매번 적는 것이 아닌 DaumPostcode
이용해 받아아온 주소 정보를 순서만 맞춰서 전달함
getData(
data.address,
data.bname,
data.buildingName,
fullAddress,
data.zonecode
);
DaumPostcode
로 기본적인 주소와 우편번호를 가져왔으니 이것을 회원가입페이지에 보여주고 추가적인 동호수를 입력할 수 있도록 하는 하는 것이 남았다.
우편번호, 기본주소가 설정된 경우 input 태그 내 보여주고 없으면 안보여주는 삼항연산자
{ZoneCode ? <input type="text" value={ZoneCode}></input> : null}
{Address ? <input type="text" value={Address}></input> : null}
우편번호와 주소가 모두 올바르게 DaumPostcode
로 받아와져 값이 set된 경우 주소 재검색 버튼과 추가주소 입력칸을 보이게 하고 아닌 경우 주소 검색버튼이 보이도록 작성
<div className="signup_Address_full">
<div className="signup_Address_input">
{ZoneCode ? <input type="text" value={ZoneCode}></input> : null}
{Address ? <input type="text" value={Address}></input> : null}
{!(ZoneCode && Address) ? (
<button name="Address" onClick={onClick_Pop}>
🔍︎ 주소 검색
</button>
) : (
<>
<input
className="signup_ExtraAddress_input"
type="text"
name="ExtraAddress"
placeholder="나머지 주소를 입력하시오"
onChange={onChange}
value={ExtraAddress}
/>
</>
)}
</div>
{!(ZoneCode && Address) ? null : (
<div className="signup_Address_btn">
<button name="Address" onClick={onClick_Pop}>
🔍︎ 주소 재검색
</button>
</div>
)}
사용자의 회원가입 POST 요청 여부 상태
const [Signup, setSignup] = useState(false);
사용자가 회원가입 요청버튼을 누르면 실행되는 API POST 요청 -> 정상적인 response를 받으면 setSignup
를 통해 초기 false 상태를 true 상태로 변경
const onSignup = async () => {
console.log("💙 Signup button click");
console.log("💙 Signup Info : ", inputs);
try {
const {
Id,
Pwd,
Username,
Phone,
Email,
Address,
Bname,
BuildingName,
ExtraAddress,
ZoneCode,
} = inputs;
const response = await axios.post("https://fakestoreapi.com/users", {
email: Email,
username: Username,
password: Pwd,
name: {
firstname: Username.slice(0, 1),
lastname: Username.slice(1),
},
address: {
city: Address,
street: String(Bname) + " " + String(BuildingName),
number: ExtraAddress,
zipcode: ZoneCode,
geolocation: {
lat: "-37.3159",
long: "81.1496",
},
},
phone: String(Phone),
});
//POST 응답 성공
console.log("💙 Signup Response: ", response.data);
//login 성공 상태
setSignup(true);
} catch (error) {
console.log("💙 Signup Error : ", error);
}
};
<div className="signup_Submit_wrap">
<button className="signup_Submit_btn" onClick={onSignup}>
회원가입
{Signup && <Redirect to="/book_curly" />}
</button>
</div>
사용자가 정상적으로 행동해 위에서부터 정보를 입력하고 회원가입 버튼을 누르는 경우 API에 유저를 등록하는 POST 요청이 실행된다. 정상으로 API가 POST 요청을 처리하게 되면 Signup
은 true값을 가지게되며 그때 메인으로 돌아갈 수 있게 <Redirect to="/book_curly" />
가 실행될 수 있게 &&
연산자를 사용함