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