03 Nav
03. Nav.jsx — 네비게이션 바
이번 단계에서 할 일
상단 네비게이션 바를 만듭니다. 클릭한 메뉴가 회색 pill 배경으로 바뀌는 기능도 구현합니다.
피그마 디자인 분석
1┌──────────────────────────────────────────────────┐2│ [로고] ┌──────┐ │3│ │ Home │ AboutMe Projects │ 높이: 99px4│ └──────┘ │5└──────────────────────────────────────────────────┘| 요소 | 값 |
|---|---|
| 전체 높이 | 99px |
| 배경색 | #ffffff |
| 활성 메뉴 배경 | #f5f5f5, 둥근 pill 모양 |
| 텍스트 색 | #1e1e1e |
| 폰트 크기 | 16px |
새로운 개념: NavLink
React Router의 NavLink는 <a> 태그처럼 링크를 만들지만,
현재 URL과 일치하면 자동으로 active 상태를 알려줍니다.
1import { NavLink } from 'react-router'2
3<NavLink4 to="#home"5 className={({ isActive }) =>6 `nav-item ${isActive ? 'nav-item--active' : ''}`7 }8>9 Home10</NavLink>to→ 이동할 경로 (href대신to를 씁니다)className→ 함수를 전달하면{ isActive }를 받아 동적 클래스 설정 가능isActive→ 현재 URL이to와 일치하면true, 아니면false
STEP 1 — Nav.jsx 작성
1import { NavLink } from 'react-router'2
3const Nav = () => {4 // 메뉴 항목: 화면에 보일 이름과 이동할 해시를 함께 관리5 const links = [6 { label: 'Home', hash: '#home' },7 { label: 'AboutMe', hash: '#aboutme' },8 { label: 'Projects', hash: '#projects' },9 ]10
11 return (12 <nav className="nav">13
14 {/* 로고 영역 */}15 <div className="nav-logo">16 <svg width="30" height="37" viewBox="0 0 30 37" fill="none">17 <path d="M0 0 L10 37 L20 0 Z" fill="#000" />18 <path d="M10 0 L30 37 L20 0 Z" fill="#000" />19 </svg>20 </div>21
22 {/* 메뉴 목록 */}23 <ul className="nav-list">24 {links.map(({ label, hash }) => (25 <li key={label}>26 <NavLink27 to={hash}28 className={({ isActive }) =>29 `nav-item ${isActive ? 'nav-item--active' : ''}`30 }31 >32 {label}33 </NavLink>34 </li>35 ))}36 </ul>37
38 </nav>39 )40}41
42export default Nav코드 설명
객체 배열 + 구조 분해 { label, hash }
1const links = [2 { label: 'Home', hash: '#home' },3 { label: 'AboutMe', hash: '#aboutme' },4 { label: 'Projects', hash: '#projects' },5]6
7{links.map(({ label, hash }) => (8 <li key={label}>...</li>9))}배열 요소가 객체이므로 { label, hash } 로 구조 분해하여
label(화면에 보일 텍스트)과 hash(이동할 위치)를 꺼냅니다.
key={label}은 왜 필요한가요? React가 목록에서 각 항목을 구별하기 위해 필요합니다. 없으면 경고가 나옵니다.
NavLink — 활성 메뉴 자동 감지
1<NavLink2 to={hash}3 className={({ isActive }) =>4 `nav-item ${isActive ? 'nav-item--active' : ''}`5 }6>7 {label}8</NavLink>to={hash}→ 이동할 URL (예:#home)className에 함수를 전달하면 React Router가{ isActive }를 자동으로 넣어줍니다isActive가true면'nav-item--active'클래스 추가
예시:
1현재 URL: #home2 Home → isActive = true → className="nav-item nav-item--active"3 AboutMe → isActive = false → className="nav-item "4 Projects → isActive = false → className="nav-item "조건부 표현식
1`nav-item ${isActive ? 'nav-item--active' : ''}``백틱`안에서${}로 JavaScript 표현식을 씁니다isActive ? A : B→isActive가true면 A,false면 빈 문자열
STEP 2 — CSS 추가
src/index.css 하단에 추가합니다.
1/* src/index.css 에 추가 */2
3/* ── 네비게이션 ──────────────────────────── */4
5.nav {6 /* 로고와 메뉴를 좌우로 배치 */7 display: flex;8 align-items: center;9 justify-content: space-between;10
11 height: 99px;12 padding: 0 24px;13 background-color: #ffffff;14 border-bottom: 1px solid #f0f0f0;15}16
17/* 메뉴 목록: 가로로 나열 */18.nav-list {19 display: flex;20 gap: 8px; /* 메뉴 간격 */21}22
23/* 메뉴 항목 기본 스타일 */24.nav-item {25 display: inline-block;26 padding: 8px 16px;27 border-radius: 100px; /* pill 모양 (완전히 둥글게) */28 font-size: 16px;29 color: #1e1e1e;30 transition: background-color 0.2s; /* 배경색이 부드럽게 변함 */31}32
33/* 마우스 올리면 배경 표시 */34.nav-item:hover {35 background-color: #f5f5f5;36}37
38/* 선택된 메뉴 */39.nav-item--active {40 background-color: #f5f5f5;41}브라우저 확인
저장 후 브라우저에서:
- 상단에 로고와 메뉴 3개가 보입니다
- 현재 URL 위치에 따라 메뉴에 회색 배경이 생깁니다
- 메뉴 클릭 → 해당 섹션으로 스크롤됩니다
정리
| 개념 | 사용 목적 |
|---|---|
NavLink | 현재 URL과 일치하는 링크에 active 상태 자동 적용 |
to | 이동할 경로 지정 (href 대신 사용) |
isActive | NavLink의 활성 여부를 className 함수로 전달 |
map | 메뉴 배열을 <li> 목록으로 변환 |
| 구조 분해 | { label, hash } 로 객체에서 필요한 값만 꺼내기 |