어쩌면 가장 중요하다고 볼 수 있는 부분이다.
홈페이지에서 상단에 메뉴 구성이 사용자가 쉽게 접근할 수 있게 하고 전체 레이아웃을 잡아주는 역할을 하기 때문에 충분히 공을 들일만한 것 같다. 그럼에도 아직은 부족하겠지만 일단적으로, 데스크탑일때는 가로로 메뉴가 보이게 하고 모바일일때는 햄버거 버튼을 클릭해야 사이드바 메뉴가 세로로 나타나도록 하는 작업이다.
| 사이드바 컴포넌트 생성
frontend/src/components/Sidebar.js
import React from 'react';
import { Link } from 'react-router-dom';
export default function Sidebar({ isOpen, toggleSidebar, user, logout }) {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 z-40" onClick={toggleSidebar}>
<div
className="fixed top-0 left-0 h-full w-64 bg-white shadow-md z-50 p-4"
onClick={(e) => e.stopPropagation()} // 내부 클릭 시 닫히지 않도록
>
<h2 className="text-xl font-bold mb-4">메뉴</h2>
<ul className="flex flex-col gap-2">
<li><Link to="/" onClick={toggleSidebar}>홈</Link></li>
<li><Link to="/posts" onClick={toggleSidebar}>게시판</Link></li>
{user ? (
<li><button onClick={() => { logout(); toggleSidebar(); }}>로그아웃</button></li>
) : (
<li><Link to="/login" onClick={toggleSidebar}>로그인</Link></li>
)}
</ul>
</div>
</div>
);
}
/ isOpen : 모바일에서 사이드바가 열려있는지 여부 확인
/ toggleSidebar : 햄버거 버튼과 사이드바 외부 클릭에서 사용
/ {user ? } : 로그인 여부에 따라 다른 메뉴 렌더링
| Navbar 수정
데스크탑 메뉴와 모바일 햄버거 메뉴로 나누고 md 이상일때와 미만일때 반응하도록 수정한다. 햄버거 버튼을 클릭하면 toggleSidebar가 실행되도록 한다.
frontend/src/components/Navbar.js
import React, { useContext } from 'react';
import { Link } from 'react-router-dom';
import { AuthContext } from '../context/AuthContext';
import { Menu } from 'lucide-react';
export default function Navbar({ toggleSidebar }) {
const { user, logout } = useContext(AuthContext);
return (
<nav className="bg-white shadow-md">
<div className="container mx-auto px-4 py-4 flex items-center justify-between">
{/* logo */}
<div className="flex items-center gap-6">
<Link to="/" className="text-lg font-bold">MyLogo</Link>
<div className="hidden md:flex items-center gap-4">
<Link to="/posts">게시판</Link>
</div>
</div>
{/* 데스크탑 메뉴 (md 이상일 때만 보임) */}
<div className="hidden md:flex items-center gap-4">
{user ? (
<>
<span>{user.username}님</span>
<button onClick={logout}>로그아웃</button>
</>
) : (
<Link to="/login">로그인</Link>
)}
</div>
{/* 모바일 햄버거 버튼 (md 미만일 때만 보임) */}
<button className="md:hidden" onClick={toggleSidebar}>
<Menu />
</button>
</div>
</nav>
);
}
/ md:hidden : 모바일에서만 보이게 설정됨.
/ lucide-react의 Menu 아이콘은 햄버거 메뉴 버튼용.
| Header 수정
실제로는 Header 자체는 껍데기 역할이라 볼 수 있다. 내부에 Navbar 컴포넌트를 넣고 toggleSidebar 함수를 props로 넘긴다.
frontend/src/components/Header.js
import React from 'react';
import Navbar from './Navbar';
export default function Header({toggleSidebar}) {
return (
<header>
<Navbar toggleSidebar={toggleSidebar} />
</header>
);
}
| Layout 수정
Layout은 이미 작업한대로 모든 페이지의 공통 구조를 가지고 있다. 여기에 사이드바 토글 상태 (sidebarOpen)를 관리하게 한다.
sidebarOpen 상태를 Sidebar 컴포넌트에 전달해 사이드바를 표시하거나 숨기게 한다.
frontend/src/components/Layout.js
import { useState, useContext } from 'react';
import Header from "./Header";
import Footer from "./Footer";
import Sidebar from "./Sidebar";
import { Outlet } from 'react-router-dom';
import { AuthContext } from '../context/AuthContext';
export default function Layout() {
const [sidebarOpen, setSidebarOpen] = useState(false);
const { user, logout } = useContext(AuthContext);
const toggleSidebar = () => setSidebarOpen(prev => !prev);
return (
<div className="flex flex-col min-h-screen">
<Header toggleSidebar={toggleSidebar} />
<Sidebar isOpen={sidebarOpen} toggleSidebar={toggleSidebar} user={user} logout={logout} />
<main className="flex-1 container mx-auto p-4">
<Outlet />
</main>
<Footer />
</div>
);
}
md 화면이 되면 이렇게 오른쪽 상단에 햄버거 버튼으로 바뀌고 버튼을 클릭하면 왼쪽에 사이드바 메뉴가 열린다.
'STUDY > Project' 카테고리의 다른 글
게시판에 반복되는 Tailwind 공통 UI 클래스 분리하기 (0) | 2025.05.16 |
---|---|
Tailwind UI 적용하기 (0) | 2025.05.13 |
페이지 라우팅 설정하기 (0) | 2025.05.11 |
반응형 내비게이션 - Navbar, lucide-react (0) | 2025.05.10 |
공통 Layout 컴포넌트 - Header, Footer, Layout (0) | 2025.05.09 |