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๋ฅผ ๋ฌด๋ฃ๋ก ์ ๊ณตํด ์ฃผ๋ ์ ํ๋ธ ์ธ๋ ํ๋๋ค์๊ฒ ๊ฐ์ฌํ ๋ฐ๋ฆ์ด๋ค. ๐ฎ๐ณ