[TIL/React] 2023/08/07
Sidebar Nav Menu ๐ reference: https://www.youtube.com/watch?v=5R9jFHlG6ik&list=WL&index=1sidebar๋ฅผ ๊ตฌํํ๊ณ ์ถ์๋ค. pedro ํ๋์ด ๋ง์์ฃผ์๋ sidebar ๊ฐ์๋ฅผ ๋ฃ๊ณ , style
Sidebar Nav Menu ๐
reference: https://www.youtube.com/watch?v=5R9jFHlG6ik&list=WL&index=1
sidebar๋ฅผ ๊ตฌํํ๊ณ ์ถ์๋ค. pedro ํ๋์ด ๋ง์์ฃผ์๋ sidebar ๊ฐ์๋ฅผ ๋ฃ๊ณ , styled-component ๋ฒ์ ์ผ๋ก ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ค.
src/App.js ๐ข
import React, { useState } from "react";
import Sidebar from "./Components/Sidebar";
function App() {
const [sidebarOpen, setSidebarOpen] = useState(false);
const toggleSidebar = () => {
setSidebarOpen(!sidebarOpen);
};
return (
<div>
<button onClick={toggleSidebar}>Toggle Sidebar</button>
<Sidebar open={sidebarOpen} onClose={toggleSidebar} />
</div>
);
}
export default App;
์ต์๋จ์์๋ 1)๋ฒํผ, 2)Sidebar ์ปดํฌ๋ํธ๋ฅผ returnํ๋ค.
1)๋ฒํผ์๋ onClick์ผ๋ก 'toggleSidebar'๋ผ๋ ํจ์๊ฐ ์ฐ๊ฒฐ๋์ด ์๋๋ฐ, sidebarOpen์ด๋ผ๋ boolean ๊ฐ์ ๋ฐ๋๋ก ์ ๋ฐ์ดํธํ๋ ๊ธฐ๋ฅ์ ์ํํ๋ค. ์ค์์น์ฒ๋ผ ๋ธ๊น๋ธ๊น ใ ใ
2)Sidebar ์ปดํฌ๋ํธ์์๋ props๋ก, 1)open์ด๋ผ๋ ์ด๋ฆ์ sidebarOpen์ด๋ผ๋ '์ํ'์ 2)onClose๋ผ๋ ์ด๋ฆ์ toggleSidebar 'ํจ์'๋ฅผ ์ ๋ฌํ๋ค.
src/Components/SidebarData.js ๐ข
export const SidebarData = [
{
title: "Home",
link: "/home",
},
{
title: "Mailbox",
link: "/mailbox",
},
{
title: "Analytics",
link: "/analytics",
},
{
title: "Dashboard",
link: "/dashboard",
},
{
title: "Images",
link: "/images",
},
];
๋จ์ํ title๊ณผ link๋ก ๊ตฌ์ฑ๋ data๋ฅผ returnํ๋ ํ์ผ์ด๋ค. Sidebar ์ปดํฌ๋ํธ์์ ์๊ธดํ๊ฒ ์ธ ์์ ์ด๋ค.
src/Components/Sidebar.js ๐ข
import React from "react";
import styled from "styled-components";
import { SidebarData } from "./SidebarData";
const SidebarContainer = styled.div`
height: 100vh;
width: ${({ open1 }) => (open1 ? "250px" : "0")};
background-color: #2f4050;
position: fixed;
top: 0;
left: 0;
transition: 0.5s;
overflow-x: hidden;
`;
const CloseSidebarButton = styled.button`
background-color: transparent;
border: none;
color: white;
cursor: pointer;
padding: 8px;
position: absolute;
top: 0;
right: 0;
`;
const SidebarList = styled.ul`
height: auto;
padding: 0;
width: 100%;
`;
const SidebarItem = styled.li`
width: 100%;
height: 60px;
list-style-type: none;
margin: 0;
display: flex;
flex-direction: row;
color: white;
justify-content: center;
align-items: center;
font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
"Lucida Sans", Arial, sans-serif;
&:hover {
cursor: pointer;
background-color: #293846;
}
${({ active }) =>
active &&
`
background-color: #293846;
`}
`;
const SidebarComponent = ({ open, onClose }) => {
const handleLinkClick = (link) => {
window.location.pathname = link;
};
return (
<SidebarContainer open1={open}>
<CloseSidebarButton onClick={onClose}>X</CloseSidebarButton>
<SidebarList>
{SidebarData?.map((val, key) => {
return (
<SidebarItem
key={key}
active={window.location.pathname === val.link}
onClick={() => handleLinkClick(val.link)}
>
{val.title}
</SidebarItem>
);
})}
</SidebarList>
</SidebarContainer>
);
};
export default SidebarComponent;
return ๋ฌธ ์ดํ๋ถํฐ ์ดํด๋ณด์. Sidebar Container ๋ด๋ถ์์ 1)๋ฒํผ๊ณผ 2)๋ฆฌ์คํธ๋ฅผ returnํ๊ณ ์๋ค.
1)onClose๋ ์ฌ์ค์ toggleSidebar ํจ์์ด๋ค. ์ต์ด์ ํด๋ฆญํ์ ๋ ์ด๊ธฐ๊ฐ์ด false์์ true๋ก ๋ณ๊ฒฝ๋์์ผ๋, ์ฌ๊ธฐ์ toggleSidebar์ ์ญํ ์ ๋ค์ true๋ฅผ false๋ก ๋ณํํ๋ ๊ฒ์ด๋ค. ํ๋ง๋๋ก sidebar๋ฅผ ๋๊ฒ ๋ค๋ ๊ฒ์ด๋ค.
2)SidebarData ๋ฐฐ์ด์ ์๋ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํด์ ์์ฐจ์ ์ผ๋ก ๋ ๋๋งํ๋ค. title์ด ๋์ค๊ณ active์ onClick์ด ์ฐ๊ฒฐ๋์ด ์๋ ๋ฆฌ์คํธ์ด๋ค.
styled component ๋ถ๋ถ์ ์ดํด๋ณด๊ฒ ๋ค.

์ปดํฌ๋ํธ์ ๊ป๋ฐ๊ธฐ๋ฅผ ๋ด๋นํ๋ ์ฝ๋์ด๋ค.
์ต์ด์ open์ ์ฌ์ค์ true์ด๊ณ open1์ด๋ผ๋ ์ด๋ฆ์ผ๋ก true๋ฅผ ๋ฐ์์ ๊ฒ์ด๋ค. width๋ 250px์ด ๋ ๊ฒ์ด๋ค. transition์ ํตํด ๋ณํ๋ฅผ ๊ฐ์งํ๊ณ 0.5์ด๊ฐ ๋ถ๋๋ฝ๊ฒ ์ ํ๋๋๋ก ์ค์ ํ๋ค.

์ ์ฝ๋์์๋ active์ ๋ํด ์ดํด๋ณผ ํ์๊ฐ ์๋ค. map์ ํตํด ๋ ๋๋ง๋๋ sidebar item์๋ active๋ก ``window.location.pathname === val.link``๋ฅผ ์ค์ ํ๊ณ ์๋ค. data๋ก ์ค์ ํ ๋งํฌ์ ํ์ฌ ํ์ด์ง์ pathname์ด ์ผ์นํ๋ฉด(์ฆ true์ด๋ฉด) background๋ฅผ ์ ์งํ๋ผ๋ ๋ช
๋ น์ด๋ค.
๊ฒฐ๊ณผ ๐ต
ํ๊ณ ๐ฃ
์ ์์ค ๋ง์ปค์ค ๋ฐํฌ๋ "์ง์ ๋ ธ๋์์ ์ฑ๊ณต์ ํ์ฌ ์๋ ์ฌ์ค์ด ์๋๋ผ ๋ฐฐ์ฐ๋ ๋ฐฉ์์ด ์ข์ฐํ๋ค"๋ผ๊ณ ์ธ๊ธํ ๋ฐ ์๋ค. ๋ช ๋ฌ ์ ๋ง ํด๋ ๋ฌธ์ ๊ฐ ์ ํ๋ฆฌ๋ฉด ๊ต์ฅํ ์คํธ๋ ์ค๋ฅผ ๋ฐ์๋ค. ์์ฆ์ ๊ฝค ๋์์ก๋ค. ํ์ฌ ์๋ ์ฌ์ค์ด ๋๋ฌด ๋ง์์ ธ์? ์ํ๊น์ง๋ง ์ฌ์ ํ ํฐ ๋ฒจํธ๋ค.
ํ๋ฆฌ์ง ์๋ ๋ฌธ์ ๋ฅผ ๋ ์์ ๋จ์๋ก ์ชผ๊ฐ๊ณ '๋ถํ ์ ๋ณต'ํ๋, ๋๋ฆ์ '๋ฐฐ์ฐ๋ ๋ฐฉ์'์ ์ ๋ฆฝํ๊ธฐ์ ๋ง์์ด ํธํด์ง ๊ฒ ๊ฐ๋ค. ํฌ๊ธฐํ์ง ์๊ธฐ ์ํด ๋ฐ์ ํ๋ ๊ณผ์ ์์ "์์ ๋จ์๋ถํฐ ์ฑ์ทจํ๋ฉด ๋๋ค๋", ๋๊ฐ ๋ด๋ ๋ปํ ์ ๋ต์ ์ต๋ํ ๊ฒ์ด๋ค. best practice๋ฅผ ๋ฌด๋ฃ๋ก ์ ๊ณตํด ์ฃผ๋ ์ ํ๋ธ ์ธ๋ ํ๋๋ค์๊ฒ ๊ฐ์ฌํ ๋ฐ๋ฆ์ด๋ค. ๐ฎ๐ณ
More to read
Amazon VPC Architecture ์ดํดํ๊ธฐ
์๋ก์ด ํ๋ก์ ํธ๋ฅผ ๊ธฐํํ๋ฉฐ, ๊ฐ๋ฐ์์ ๋ฌด์์ ๊ฐ์ฅ ๋จผ์ ๊ณ ๋ฏผํด์ผ ํ๋์ง ๋ค์ ๋์๋ณด๊ฒ ๋์์ต๋๋ค.ํ๋๋ ํ๋ก ํธ์๋๊ฐ ๋ชจ๋ ์ค๊ณ์ ์ถ๋ฐ์ ์ด๋ผ๊ณ ๋ฏฟ์์ต๋๋ค. ์ ์ ๊ฐ ๋ฌด์์ ๋ณด๊ณ , ์ด๋ค ํ๋ฆ์์ ๋จธ๋ฌด๋ฅด๊ณ ์ดํํ๋์ง์ ๋ํ ์ดํด ์์ด ์๋น์ค๋ฅผ ๋ง๋ ๋ค๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ๊ธฐ
'์์ฌ์ดํธ'ํ๋ก ํธ์๋ ๊ด์ ์ผ๋ก ์๊ณ ๋ฆฌ์ฆ ์ดํดํ๊ธฐ
์ค๋๋ง์ ๋ฐฉ๋ฒ๋ก ์ ๊ดํ ๊ธ์ ์ฐ๊ฒ ๋์์ต๋๋ค. ์ต๊ทผ ์ํฉ์ ์ด๋ ์ต๋๋ค. SSAFY์์๋ ํ๋ฃจ์ ์์ฒญ๋ ์์ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ค์ ๊ณผ์ ๋ก ์ํํ๊ฒ ๋ฉ๋๋ค. ๊ทธ ๊ณผ์ ์์, '๊ตฌํ๋ ฅ'์ด ๋งค์ฐ ๋จ์ด์ง๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ์์ ํ ์ด๋ ค์ด ๋ฌธ์ ๋ผ๋ฉด '์์ฌ์'์ด๋ผ๋ ๊ฐ์ ์กฐ์ฐจ ๋๋ผ์ง
SubnetVPC ์ค๊ณ์ ์์: IP์ Subnet
๋ฐ๋ณต๋๋ ๋ฃจํด ์์์ ์ป์ ์์ ๊ฐ์ ๋ฐํ ์ผ์, ์ด์ ๋ ๊ธฐ์ ์ ์คํํธ๋ผ์ ๋ํ๊ธฐ ์ํ ๊ฐ์ธ ํ๋ก์ ํธ์ ์ฐฉ์ํ๊ณ ์ ํฉ๋๋ค.์ด๋ฒ ํ๋ก์ ํธ์ ๋ชฉํ๋ ๋จ์ํ ํฌํธํด๋ฆฌ์ค ๊ตฌ์ถ์ ๋์ด, ์ค์ ์๋น์ค ์์ค์ ๋ธ๋ก๊ทธ ์์คํ ๊ตฌํ๊ณผ ๋ค๊ตญ์ด ์ฒ๋ฆฌ ์ ์ฉ ๋ฑ ์ค๋ฌด์ ๊ฐ๊น์ด ์ญ๋์ ํ ๋จ๊ณ