๐
TIL - 2022.02.15
February 15, 2022
์ค๋ํ์ผ ๐จ๐ปโ๐ป .
- ๋ฉด์ ์ค๋น ๐ฅ
- ์ฝ๋ฉํ ์คํธ โ๏ธ
๊ธฐ๋ก โ๐ป .
- ์ด๋ ฅ์๋ฅผ ์ ์ถํ ํ์ฌ์์ ์ฐ๋ฝ์ด ์๋ค. ์๊ณ ๋ฆฌ์ฆ ํ ์คํธ๊ฐ ์๋ ์ค๋ฌด์ ๊ฐ๊น์ด ๋ด์ฉ์ผ๋ก ๊ตฌ์ฑ๋ ๊ณผ์ ๋๋ ํผ๊ทธ๋ง url๊ณผ json ํ์ผ์ ๋ฉ์ผ๋ก ๋ฐ์ ํผ๊ทธ๋ง ๋ด์ฉ๋๋ก ๋ทฐ ์์ ๋ถํฐ ์งํํ๋ค
ํ๋ก์ ํธ ํด๋ ๊ตฌ์กฐ
App.js์ Navigation ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ ์ฌ์ฉ, Navigation ์ปดํฌ๋ํธ ์์์ MobileMenu๋ฅผ ๋ชจ๋ฌ ํ์ ํํ๋ก ์ฌ์ฉ
- ์ฃผ์ด์ง ์กฐ๊ฑด ์ค ๋ฐ์ํ์ ์ ์ฉํ์ฌ ๋ชจ๋ฐ์ผ ์ฌ์ด์ฆ๊ฐ ๋์์ ์ ์๋จ์ ๋ค๋น๊ฒ์ด์ ์ด ํ๋ฒ๊ฑฐ ๋ฉ๋ด ๋ฒํผ๊ณผ ๋ก๊ณ ๋ง ๋จ๊ณ ํ๋ฒ๊ฑฐ ๋ฉ๋ด ๋ฒํผ์ ํด๋ฆญ ์ ์ข์ธก์์ ์ฐ์ธก์ผ๋ก fade-in ์ ๋๋ฉ์ด์ ์ ์ ์ฉํ๋ ์กฐ๊ฑด์ด ์์ด ์ด ์์ ๋ถํฐ ์งํํจ, ์ถ๊ฐ์ ์ผ๋ก ํ๋ฒ๊ฑฐ ๋ฉ๋ด๊ฐ ๋์ฌ ์ ์ฐ์ธก ๋น ์ฌ๋ฐฑ์ ํด๋ฆญํ์ฌ ํ๋ฒ๊ฑฐ ๋ฉ๋ด๋ฅผ ๋ซ๋ ๊ธฐ๋ฅ๊น์ง ์ถ๊ฐํจ

- ๋ค๋น๊ฒ์ด์ ์ปดํฌ๋ํธ๋ฅผ style-component, @media screen๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ก๊ฐ์ด 500px์ด ๋์์๋ ๋ชจ๋ฐ์ผ ๋ฉ๋ด๋ก ๋ณ๊ฒฝ
const NavBox = styled.div`
@media screen and (max-width: 500px) {
#mb_menu {
display: none;
margin-right: 19px;
}
@media screen and (max-width: 500px) {
width: 100%;
padding-left: 23px;
#ateam_logo {
width: 91.8px;
height: 12px;
}
#mb_menu {
display: block;
}
}
`
const AnotherBox = styled(LogoBox)`
justify-content: flex-end;
padding-left: 0;
padding-right: 40px;
@media screen and (max-width: 500px) {
display: none;
}
}
`- Navigation ์ปดํฌ๋ํธ๋ ๋ฐ์คํฌํ ์ฌ์ด์ฆ์์ ๋ ธ์ถ๋๋ค. MobileMenu ์ปดํฌ๋ํธ๋ ๋ชจ๋ฐ์ผ ์ฌ์ด์ฆ๊ฐ ๋์์ ์ display: bolck์ ์ฌ์ฉํ์ฌ ๋ ธ์ถ์์ผ์ฃผ๋ฏ๋ก ๊ฐ์ ์ ํด์ง ๊ฐ๋ก ๊ฐ์ ๋ฐ์ํ์ฌ ๋ ธ์ถ๋๋ค. ๋ชจ๋ฐ์ผ ๋ฉ๋ด๋ Navigation ์ปดํฌ๋ํธ์์ useState๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ๋ด ์คํ ์ํ ๊ด๋ฆฌ๋ฅผ ํ๋ฉฐ props๋ก MobileMenu ์ปดํฌ๋ํธ์ openModal ํจ์๋ฅผ ์ ๋ฌํ์ฌ ๋ชจ๋ฐ์ผ ๋ฉ๋ด ํด๋ฆญ ์ useState ์ํ ๊ฐ์ ture๋ก ๋ณ๊ฒฝํ์ฌ ๋ฉ๋ด๋ฅผ ์คํํ๋ค. ๋ชจ๋ฐ์ผ ๋ฉ๋ด ์์ญ ๋ฐ์ ํด๋ฆญ ์ useEffect๋ฅผ ์ฌ์ฉํ์ฌ โmousedowโ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๊ณ handleClickOutside ํจ์๋ก ๋ชจ๋ฐ์ผ ๋ฉ๋ด ์ํ ๊ฐ์ false๋ก ๋ณ๊ฒฝํ์ฌ ๋ฉ๋ด๋ฅผ ๋ซ๊ฒ ํ๊ณ useRef๋ฅผ ์ฌ์ฉํ์ฌ Navigation ์ปดํฌ๋ํธ ์์ญ์ ์ค์
Navigation.js
const Navigation = () => {
const wrapperRef = useRef();
const [modalOpen, setModalOpen] = useState(false);
const openModal = () => {
setModalOpen(true);
};
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
});
const handleClickOutside = (event) => {
if (wrapperRef && !wrapperRef.current.contains(event.target)) {
setModalOpen(false);
}
};
return (
<>
<NavBox ref={wrapperRef}>
{/* ๋ฐ์คํฌํ ๋ค๋น๊ฒ์ด์
*/}
<LogoBox>
{/* ๋ชจ๋ฐ์ผ ๋ค๋น๊ฒ์ด์
*/}
<MobileMenuBar id="mb_menu" onClick={openModal} />
<AteamLogo id="ateam_logo" />
</LogoBox>
<AnotherBox>
<BtnTwo>
<NavIcon fill="#fff" />
<NavText>A ๊ฐ๊ณต ์
์ฒด</NavText>
</BtnTwo>
<Line />
<LogOutBtn>๋ก๊ทธ์์</LogOutBtn>
</AnotherBox>
</NavBox>
<MobileMenu open={modalOpen} />
</>
);
};MobileMenu.js
const MobileMenu = (props) => {
const { open } = props;
return (
<>
<ModalBox className={open ? "openModal modal" : "modal"}>
{open ? (
<ModalBackground>
<ModalContents>
<ModalHead>
<LogoBlue />
</ModalHead>
<ModalBody>
<BtnTwo>
<NavIcon fill="#323D45" />
<NavText>A ๊ฐ๊ณต ์
์ฒด</NavText>
</BtnTwo>
<LogOutBtn>๋ก๊ทธ์์</LogOutBtn>
</ModalBody>
</ModalContents>
</ModalBackground>
) : null}
</ModalBox>
</>
);
};- ๋ชจ๋ฐ์ผ ๋ฉ๋ด ์คํ ์ ์ข์ธก์์ ์ฐ์ธก์ผ๋ก ๋ฐ๋ ค๋ค์ด์ค๋ fade-in ์๋๋ฉ์ด์ ๊ณผ ๋ฉ๋ด ๋ท๋ฐฐ๊ฒฝ ์๋๋ฉ์ด์ ์ @keyframes์ ์ฌ์ฉํ์ฌ ์ ์ฉ
- ๋ท๋ฐฐ๊ฒฝ ์๋๋ฉ์ด์
const ModalBackground = styled.div`
width: 100%;
height: 100vh;
overflow: hidden;
background-color: rgba(50, 61, 69, 0.5);
position: fixed;
top: 0;
left: 0;
z-index: 9;
animation: fadeInBackground 0.35s;
@keyframes fadeInBackground {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`;- ์ข์ธก์์ ์ฐ์ธก์ผ๋ก ์๋๋ฉ์ด์
const ModalContents = styled.div`
width: 75%;
height: 100vh;
overflow: hidden;
background-color: #fff;
animation: fadeInModal 0.45s;
@keyframes fadeInModal {
from {
opacity: 0;
margin-left: -600px;
}
to {
opacity: 1;
margin-left: 0;
}
}
`;