React 로그인 Modal 만들기

로그인 Modal 만들기

기존에 개인 프로젝트로 로그인 창을 만들게 되면 별도의 웹 페이지로 로그인 화면을 구현을 했다. 하지만 좀 더 깔끔하고 반응적인 방법을 찾다가 Modal에 대해 알게 됐고 Modal을 이용해 Login 화면을 구현해 보고자 한다.

로그인 컴포넌트 만들기

가장 바깥 Wrapper는 로그인 버튼을 누른 상태와 누르지 않은 상태를 보여줘야 함으로 조건절을 이용해 classname을 변경하도록 설정한다.

// Login 페이지가 열리면 modal-wrapper가 선택된다. 
<div className={open ? "modal-wrapper" : null}>

내부 컴포넌트도 상태에 따라 보이거나 보이지 않게 상태를 변경해줄 필요가 있어 조건절을 통해 내부 컴포넌트를 가져올 수 있도록 설정한다.

{open ? (
<div className="login-modal">
<div className="login-header">로그인</div>
<div className="login-input">
<div className="login-id">
<input
className="email"
type="email"
id="email"
placeholder="Email"
onChange={onChangeEmail}
/>
</div>
<div className="login-password">
<input
className="password"
type="password"
id="password"
placeholder="Password"
onChange={onChangePassword}
/>
</div>
<div className="close-login">
<button className="close-button" onClick={close}>
닫기
</button>
</div>
</div>
</div>
) : null}

LoginTemplate.js

import React, { useState, useCallback } from "react";
import styled from "styled-components";
import "../assets/css/modal.css";

const LoginTemplate = ({ open, close }) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const onChangeEmail = useCallback(
(e) => {
setEmail(e.target.value);
},
[email]
);

const onChangePassword = useCallback(
(e) => {
setPassword(e.target.value);
},
[password]
);

return (
// Login 페이지가 열리면 modal-wrapper가 선택된다.
<div className={open ? "modal-wrapper" : null}>
{open ? (
<div className="login-modal">
<div className="login-header">로그인</div>
<div className="login-input">
<div className="login-id">
<input
className="email"
type="email"
id="email"
placeholder="Email"
onChange={onChangeEmail}
/>
</div>
<div className="login-password">
<input
className="password"
type="password"
id="password"
placeholder="Password"
onChange={onChangePassword}
/>
</div>
<div className="close-login">
<button className="close-button" onClick={close}>
닫기
</button>
</div>
</div>
</div>
) : null}
</div>
);
};

export default LoginTemplate;

컴포넌트 스타일링 하기

.modal-wrapper{
position: fixed;
top:0;
left:0;
width:100%;
height:100%;
background:rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
animation: modal-bg-show .5s;
}

.login-modal{
width: 90%;
max-width: 400px;
margin:0 auto;
border-radius: .3rem;
background-color: #fff;
animation: modal-show .5s;
overflow: hidden;
}

.login-input{
padding-top:10px;
}

.login-header{
position: relative;
padding: 16px 64px 16px 16px;
background-color: #f1f1f1;
font-weight: 700;
}

.login-id{
padding:10px;
display: flex;
align-items: center;
justify-content: center;
}

.login-password{
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 20px;
}

.email{
padding-top:5px;
padding-bottom:5px;
padding-left: 15px;
padding-right: 15px;
width: 290px;
height: 30px;
font-size: 14px;
border: 1px solid rgb(222, 226, 230);
}

.password{
padding-top:5px;
padding-bottom:5px;
padding-left: 15px;
padding-right: 15px;
width: 290px;
height: 30px;
font-size: 14px;
border: 1px solid rgb(222, 226, 230);
}


.close-login{
border-top: 1px solid;
padding: 12px 16px;
text-align: right;
}

.close-button{
padding: 6px 12px;
color: #fff;
background-color: #6c757d;
border-radius: 5px;
font-size: 13px;
}


@keyframes modal-show {
from {
opacity: 0;
margin-top: -50px;
}
to {
opacity: 1;
margin-top: 0;
}
}
@keyframes modal-bg-show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

작동 확인하기

작성이 완료된 LoginTemplate를 갖고 메인 화면에서 보내는 open 상태에 따라 Login Modal이 잘 작동하는지 확인한다.

App.js

import { useCallback, useState } from "react";
import LoginTemplate from "./components/LoginTemplate";
// import "./assets/css/modal.css";

function App() {
const [open, setOpen] = useState(false);

const onClickButton = useCallback(() => {
console.log("open login modal");
setOpen(!open);
}, [open]);

return (
<div>
<button onClick={onClickButton}>로그인 Modal Pop Up</button>
<LoginTemplate open={open} close={onClickButton} />
</div>
);
}

export default App;
Share