์ผ์ ์ ๋ธ๋ผ์ฐ์ ํฌ๊ธฐ๋ฅผ ์ค์ฌ๋ ํค๋๋ฅผ ๋ฐ๋ผ๋ค๋๋ ๋ชจ๋ฌ์ ๊ตฌํํ์๋๋ฐ,
์ ๋๋ค๊ฐ ์ด๋์ ๋ณด๋ ์์น๊ฐ ์ ๋ง๋๊ฒ ์๋๊ฐ...
์๋ฌด๋ฆฌ position์ ๋ณ๊ฒฝํด ๊ฐ๋ฉฐ ์ฝ์ง์ ํด๋ ์๋๊ธธ๋ ๋ชจ๋ฌ ํด๋ก์ง ๋ฐฉ์์ ๋ฐ๊ฟจ๋ค.
๊ธฐ์กด์๋ LogOutModal ์ปดํฌ๋ํธ์์ ์ปจํ ์ธ ๋ฐ์ค์ธ modal-logout-content-1์ ์์ ์์, ์ฆ ๋ฐ์ค ๋ฐ๊นฅ์ ํด๋ฆญํ ๊ฒฝ์ฐ ๋ชจ๋ฌ์ด ํด๋ก์ง๋๊ฒ ํ์๋ค.
import { useState } from "react";
import LogOutModal from "./Modal/LogOutModal";
const Navigation = ({ userObj }) => {
//Log Out Modal
const [isOpenLogOutModal, setIsOpenLogOutModal] = useState(false);
const handleOpenLogOutModal = () => {
setIsOpenLogOutModal((prev) => !prev);
};
const handleCloseLogOutModal = () => {
setIsOpenLogOutModal(false);
}
return (
//์๋ต
<LogOutModal
userObj={userObj}
onClose={handleCloseLogOutModal}
show={isOpenLogOutModal}
/>
//์๋ต
const LogOutModal = ({ show, userObj, onClose }) => {
//์๋ต
return (
<div className={`modal-layout ${show ? "show" : ""}`} onClick={onClose}>
<div className="modal-layout-inside">
<div className="modal-logout">
<div
className="modal-logout-content-1"
onClick={(e) => e.stopPropagation()}
>
//์๋ต
.modal-layout {
z-index: 999;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
opacity: 0;
transition: all 0.15s ease-in-out;
pointer-events: none;
.modal-layout-inside {
position: fixed;
left: 0;
right: 0;
top: 68%;
display: flex;
.modal-logout {
position: sticky;
left: -13px;
.modal-logout-content-1 {
width: 300px;
//์๋ต
๐ฅบ ๋ก๊ทธ์์ ๋ชจ๋ฌ์ ๋ค๋ฃฐ ๋ ์๋ ๋ ๊ฐ์ง๋ฅผ ๋์์ ๊ตฌํํ๊ณ ์ถ์๋ค.
๋ชจ๋ฌ์ด ํค๋์ ํ๋กํ ์ฌ์ง ์์ ๋ฑ ๋ฌ๋ผ ๋ถ์ด ์์ ๊ฒ.
๋ชจ๋ฌ ์ปจํ ์ธ ๋ฐ์ค ์ธ๋ถ ํด๋ฆญ ์ ๋ชจ๋ฌ ์ฐฝ์ด ๋ซํ ๊ฒ.
์ ๋๋๊ฒ ์ ๊ฐ์๊ธฐ ์๋๋ ๊ฑธ๊น, ์ค์ ์๋๋ถํฐ ์ฝ๋๊ฐ ์ด์ํ๋๋ฐ ์ด์ํ๊ฒ ์ ์๋ํ๋๊ฑด ์๋๊น ์ถ๊ธฐ๋ ํ๋ค...๐ฅฒ
์ํ๊น๊ฒ๋ ์ ์ ์๋๋ ์ด ์ฝ๋๋ก๋ 1๋ฒ์ด ๋ถ๊ฐ๋ฅํ๊ฒ ๋์ด๋ฒ๋ ธ๋ค.
position์ ๋ฐ๊พธ๋ฉฐ ๊ณ์์ ์ธ ์ฝ์ง์ ํ์ง๋ง ๊ณ์์ ์ธ ์คํจ์ ์ง์ ๋จธ๋ฆฌ๊ฐ ๋ ์ฆ์... ๋ชจ๋ฌ ํด๋ก์ง ๋ฐฉ์์ ๋ฐ๊พธ๊ธฐ๋ก ํ๋ค.
import { useEffect, useRef, useState } from "react";
import LogOutModal from "./Modal/LogOutModal";
const Navigation = ({ userObj }) => {
const outsideOfLogOutModal = useRef();
//Log Out Modal
const [isOpenLogOutModal, setIsOpenLogOutModal] = useState(false);
const handleOpenLogOutModal = () => {
setIsOpenLogOutModal((prev) => !prev);
};
const handleCloseLogOutModal = ({ target }) => {
if (isOpenLogOutModal && !outsideOfLogOutModal.current.contains(target))
setIsOpenLogOutModal(false);
};
useEffect(() => {
window.addEventListener("click", handleCloseLogOutModal);
return () => {
window.removeEventListener("click", handleCloseLogOutModal);
};
});
return (
//์๋ต
<div ref={outsideOfLogOutModal}>
<LogOutModal userObj={userObj} show={isOpenLogOutModal} />
</div>
//์๋ต
const outsideOfLogOutModal = useRef();
useRef()๋ฅผ ์ฌ์ฉํ๋ฉด DOM์์ ๋ด๊ฐ ์ํ๋ ์์๋ฅผ ์ง์ ํ ์ ์๋ค.
๋ชจ๋ฌ ์ปดํฌ๋ํธ์ ํด๋นํ๋ ์์ญ์ ํฌํจํ ์์๋ฅผ ์ง์ ํ๊ธฐ ์ํด outsideOfLogOutModal๋ผ๊ณ ๋ณ์ ์ด๋ฆ์ ์ฃผ๊ณ useRef()๋ฅผ ์ฌ์ฉํด ๋ณด์.
window.addEventListener("click", handleCloseLogOutModal);
๋ธ๋ผ์ฐ์ ์ ์ด๋ ค์๋ window ๊ฐ์ฒด, ์ฆ ๋ธ๋ผ์ฐ์ ํ๋ฉด์ ํด๋ฆญํ๋ฉด handleCloseLogOutModal ์ด๋ฒคํธ๊ฐ ์คํ์ด ๋๋ค.
(.show)์ผ ๋ฟ, ํด๋ฆญ์ด๋ฒคํธ๊ฐ ์คํ๋ ๋ useRef()๋ก ๊ฐ๋ฆฌํค๋ DOM์์๋ ๋๊ฐ์ด ๋ชจ๋ฌ์ปดํฌ๋ํธ ๋ถ๋ถ์์ ์ ์ ์๋ค.
if (isOpenLogOutModal && !outsideOfLogOutModal.current.contains(target))
isOpenLogOutModal์ state๊ฐ true, ์ฆ, ๋ก๊ทธ์์ ๋ชจ๋ฌ์ด ์ด๋ ธ์ ๋,
๊ทธ๋ฆฌ๊ณ ๋์์ outsideOfLogOutModal.current.contains(target)์ด false์ผ ๋, ์ฆ, ํด๋ฆญํ ํ๊ฒ์ด ๋ชจ๋ฌ ์ปดํฌ๋ํธ๊ฐ ์ํ ๋ถ๋ถ์ด ์๋ ๋ชจ๋ฌ์ ์ธ๋ถ๋ฅผ ํด๋ฆญํ์ ๋ ๋ชจ๋ฌ์ ํด๋ก์งํ๋ค.
๐ contains ๋ฉ์๋๋ ์ด๋ฒคํธ์ ํ๊ฒ์ด ref์ ์ํด ์๋์ง ์ฆ, ์๋
์ธ์ง ์๋ ค ์ฃผ๋ ๋ฉ์๋์ด๋ค.
๋ฐ๋ผ์ LogOutModal ์ปดํฌ๋ํธ ์๋จ์ div๋ฅผ ํ๋ ์๋ก ๋ง๋ค๊ณ , ๊ทธ div์ ref๋ฅผ ์์ฑํ์ฌ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ์ ์ฉ๋ ์์ญ์ ์ค์ ํ๋ฉด ๋๋ค.
const LogOutModal = ({ show, userObj }) => {
//์๋ต
return (
<div className={`modal-layout ${show ? "show" : ""}`}>
<div className="modal-logout">
<div className="modal-logout-content-1">
๊ธฐ์กด์ ์๋ onClose ํ๋กํผํฐ๋ ์ ๊ฑฐํ๋ค.
.modal-layout {
z-index: 999;
position: absolute;
left: 0;
top: 68vh;
display: flex;
opacity: 0;
transition: all 0.15s ease-in-out;
pointer-events: none;
.modal-logout {
position: fixed;
top: 68vh;
.modal-logout-content-1 {
width: 300px;
//์๋ต
์์ ์์์ธ header๊ฐ position: relative์ธ๊ฑด ๋์ผํ๋ค.
๋จผ์ ๋ชจ๋ฌ ์ปดํฌ๋ํธ ์ต์๋จ div์ธ modal-layout์ position: absolute๋ฅผ ์ฃผ์ด ๋ถ๋ชจ์ธ ํค๋์ ๋ถ์ธ๋ค.
๊ทธ๋ฌ๊ณ ๋์ ์ปจํ
์ธ ๋ฐ์ค ๋ฐ๋ก ์๋จ div์ธ modal-logout์ position: fixed๋ฅผ ์ค์ ํค๋ ์์ญ์ ๋ทฐํฌํธ์ ๊ณ ์ ์ํจ๋ค.
๐ ์ ์ฒด์ ๋ฐ๊นฅ ๋ถ๋ถ์ ํด๋ฆญํ์ ๋๋ง ๋ชจ๋ฌ์ด ๋ซํ๊ธฐ ๋๋ฌธ์ ์ปจํ ์ธ ๋ฐ์ค ์๋จ div๋ค์๋ height ๊ฐ์ ์ฃผ์ง ๋ง์์ผ ํ๋ค. ๊ธฐ์กด์ ํ๋ ๋ฐฉ์๊ณผ ์์ ๋ฐ๋๋ค.

๐ฅบ ํด ์ด์ ๋ ๋ค ๋๋ค.
๋ชจ๋ฌ์ด ํค๋์ ํ๋กํ ์ฌ์ง ์์ ๋ฑ ๋ฌ๋ผ ๋ถ์ด ์์ ๊ฒ.
๋ชจ๋ฌ ์ปจํ ์ธ ๋ฐ์ค ์ธ๋ถ ํด๋ฆญ ์ ๋ชจ๋ฌ ์ฐฝ์ด ๋ซํ ๊ฒ.
์์์์ํ ์ค๋ฅ๊ฐ ์ฐธ ๋ง๋ค.
๊ณผ์ฐ ๋๋ ์ด ํ๋ก์ ํธ๋ฅผ ์ ๋ง๋ฌด๋ฆฌ ํ ์ ์์ ๊ฒ์ธ๊ฐ...!