button.js
import React, { Component } from "react"; import SignIn from "./SignIn"; class button extends Component { constructor(props) { super(props); this.state = { isModalOpen: false, }; } openModal = () => { this.setState({ isModalOpen: true }); }; closeModal = () => { this.setState({ isModalOpen: false }); }; render() { return ( <> <button onClick={this.openModal}>Modal Open</button> <SignIn isOpen={this.state.isModalOpen} close={this.closeModal} /> </> ); } } export default button;
버튼을 누를시 로그인 모달이 켰다가 꺼졌다가 하게 만들었다.
isModalOpen를 state에 담아서 true일땐 modal이 나오고 false일땐 사라지는 버튼을 만들었다.
<SignIn isOpen={this.state.isModalOpen} close={this.closeModal} />
를 프롭스로 보낼것이다.
SignIn.js
import React, { Component } from "react"; import { Link } from "react-router-dom"; import "./SignIn.scss"; class SignIn extends Component { state = { email: "", password: "", }; loginHandler = (e) => { const { name, value } = e.target; this.setState({ [name]: value }); }; ////계산된 속성명 사용 loginClickHandler = () => { const { email, password } = this.state; fetch("http://10.58.2.17:8000/auth/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ email, password, }), }) .then((res) => res.json()) .then((res) => console.log(res)); }; render() { const { isOpen, close } = this.props; //아까 버튼에서 props로 가져온것 return ( <> {isOpen ? ( ////만약 isopen(this.state.isModalOpen)이 true일때 코드를 실행 false면 null /// <div onClick={close}> 로그인창 말고 회색 바탕을 누를시 모달이 꺼지게 만듬 ///<span className="close" onClick={close}>×</span> x버튼 누를시 꺼짐 ////<div className="modalContents" onClick={isOpen}> 로그인 화면은 버튼 클릭해서 들어오면 /// true인 상태로 있어서 화면이 안꺼진다. <div className="modal"> <div onClick={close}> <div className="loginModal"> <span className="close" onClick={close}> × </span> <div className="modalContents" onClick={isOpen}> <img className="signinIcon" src="/Images/SignIn/signinIcon.png" /> <input name="email" className="loginId" type="text" placeholder="아이디" onChange={this.loginHandler} /> <input name="password" className="loginPw" type="password" placeholder="비밀번호" onChange={this.loginHandler} /> <div className="loginMid"> <label className="autoLogin" for="hint"> {" "} <input type="checkbox" id="hint" /> 로그인 유지하기 </label> <div className="autoLogin">아이디/비밀번호 찾기</div> </div> <button className="loginBtn" onClick={this.loginClickHandler}> {" "} 로그인{" "} </button> <div className="socialBox"> <div className="kakao"> <img className="kakaoLogo" src="/Images/SignIn/kakao.png" /> <div className="kakaoText">카카오 계정으로 신규가입</div> </div> <div className="facebook"> <img className="facebookLogo" src="/Images/SignIn/facebook.png" /> <div className="facebookText"> 페이스북 계정으로 신규가입 </div> </div> </div> <div className="loginEnd"> <div className="loginLine"> 회원이 아니신가요? <Link to="/signup">회원가입</Link> </div> <div className="noUser">비회원 주문 조회</div> </div> </div> </div> </div> </div> ) : null} </> ); } } export default SignIn;
>
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.6); ///배경에 픽스를 주고 투명도를 준다.
>
.loginModal {
width: 480px;
height: 621px;
background-color: white;
position: relative;
box-sizing: border-box;
margin: 50px auto;
padding: 20px;
background: #fff; //로그인 배경이다
>
.close {
float: right;
font-size: 25px;
}
.modalContents {
margin: 0 auto;
width: 100%;
position: relative;
padding: 0 20px 32px;
box-sizing: border-box;
display: flex;
justify-content: center;
flex-direction: column;
>
.signinIcon {
width: 150px;
margin: 0 auto;
}
>
.loginId {
margin-top: 30px;
border-radius: 2px;
width: 100%;
height: 40px;
border: 1px solid #e5e5e5;
padding: 9px 12px;
outline: none;
box-sizing: border-box;
}
input::placeholder {
color: #999999;
}
.loginPw {
margin-top: 15px;
border-radius: 2px;
width: 100%;
height: 40px;
border: 1px solid #e5e5e5;
padding: 9px 12px;
outline: none;
box-sizing: border-box;
}
>
.loginMid {
display: flex;
justify-content: space-between;
align-items: center;
.autoLogin {
font-size: 12px;
color: #8d8d8d;
line-height: 3;
}
}
.loginBtn {
height: 40px;
font-size: 14px;
padding: 13px 30px;
cursor: pointer;
background-color: black;
color: white;
line-height: 1px;
margin-top: 20px;
margin-bottom: 12px;
border-radius: 3px;
border-style: none;
}
>
.socialBox {
margin-bottom: 30px;
.kakao {
background-color: #feec34;
border-color: #feec34;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
margin-bottom: 10px;
border-radius: 3px;
>
.kakaoLogo {
width: 24px;
height: 25px;
}
.kakaoText {
width: 300px;
font-size: 15px;
text-align: center;
display: inline-block;
box-sizing: border-box;
}
}
>
.facebook {
background-color: #21538a;
border-color: #21538a;
height: 40px;
display: flex;
justify-content: center;
box-sizing: border-box;
color: #fff;
border-radius: 3px;
>
.facebookText {
padding-top: 12px;
width: 310px;
color: #fff;
font-size: 15px;
text-align: center;
box-sizing: border-box;
}
>
.facebookLogo {
padding-top: 7px;
width: 24px;
height: 25px;
}
}
}
.loginEnd {
text-align: center;
font-size: 11px;
>
.loginLine {
color: #bcbcbc;
font-size: 11px;
margin-bottom: 35px;
a {
color: black;
text-decoration: underline;
cursor: pointer;
}
}
.noUser {
text-decoration: underline;
}
}
}
}
}
감사합니다 스타일 구성 참고하겠습니다.