본문 바로가기
React

[React] 웹페이지 메뉴바 드롭다운 만들기

by teamnova 2025. 8. 6.
728x90

안녕하세요 

오늘은 웹페이지 상단에 위치한 메뉴바에 드롭다운으로 세부 메뉴 목록을 구성해보도록 하겠습니다. 

드롭다운 메뉴는 카테고리가 많을때 사용자가 쉽게 원하는 목록을 찾을 수 있도록 합니다. 

 

드롭다운 뉴의 주 목적:

 

1. 공 율성

  • 네비게이션 바의 간이 한적일 때
  • 많은 뉴 항목을 한 줄에 모두 표시하기 어려울 

2.  정보 

  • 관련된 메뉴들 카테고리별로 그룹화
  • 사용자가 원하 정보를 더 쉽게 찾  있게 함

3. 사용 경험(UX) 개선

  •  뉴 구조 단순
  • 시각적 혼란을 줄 직관적인 네게이션 제공

 사례들:

  • 핑몰: "남의류"  "상", "하", "신발" 
  •  사이트: "제품" → "소프트웨어", "하드어", "서비" 등
  • 포트폴리오: "프로젝트"  "웹개발", "모바일앱", "AI" 등

으로, 메뉴 항목 많아서 공간이 부하고, 관련 항목들을 적으 분류하고 싶  드롭다운 메뉴가 가장 효과적입니다 

 

 

 

기존 Header 의 메뉴바에 드롭 다운 메뉴를 추가해줍니다. 

Header.jsx 

 const dropdownItems = {
    about: [
      { label: "개인정보", to: "about" },
      { label: "경력사항", to: "about" },
      { label: "학력사항", to: "about" },
      { label: "기술스택", to: "about" },
    ],
    projects: [
      { label: "웹 개발", to: "projects" },
      { label: "모바일 앱", to: "projects" },
      { label: "데이터 분석", to: "projects" },
      { label: "AI/ML", to: "projects" },
      { label: "블록체인", to: "projects" },
    ],
    contact: [
      { label: "이메일", to: "contact" },
      { label: "전화번호", to: "contact" },
      { label: "소셜미디어", to: "contact" },
      { label: "위치", to: "contact" },
    ],
  };

 

 

Header.jsx

 Header 컴포넌트를 수정해서 About, Projects, Contact 각각에 드롭다운 메뉴를 추가 합니다. 

 

          {/* About 드롭다운 */}
          <div
            className="relative inline-block"
            onMouseEnter={() => handleMouseEnter("about")}
            onMouseLeave={handleMouseLeave}
          >
            <Link
              to="about"
              spy={true}
              smooth={true}
              offset={-80}
              duration={500}
              className="cursor-pointer hover:text-indigo-500 transition-colors"
            >
              About
            </Link>
            {activeDropdown === "about" && (
              <div className="absolute top-full left-0 mt-2 bg-white shadow-lg border border-gray-200 rounded-lg py-2 min-w-40 z-50">
                {dropdownItems.about.map((item, index) => (
                  <Link
                    key={index}
                    to={item.to}
                    spy={true}
                    smooth={true}
                    offset={-80}
                    duration={500}
                    className="block px-4 py-2 text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 transition-colors text-sm"
                  >
                    {item.label}
                  </Link>
                ))}
              </div>
            )}
          </div>

          {/* Projects 드롭다운 */}
          <div
            className="relative inline-block"
            onMouseEnter={() => handleMouseEnter("projects")}
            onMouseLeave={handleMouseLeave}
          >
            <Link
              to="projects"
              spy={true}
              smooth={true}
              offset={-80}
              duration={500}
              className="cursor-pointer hover:text-indigo-500 transition-colors"
            >
              Projects
            </Link>
            {activeDropdown === "projects" && (
              <div className="absolute top-full left-0 mt-2 bg-white shadow-lg border border-gray-200 rounded-lg py-2 min-w-40 z-50">
                {dropdownItems.projects.map((item, index) => (
                  <Link
                    key={index}
                    to={item.to}
                    spy={true}
                    smooth={true}
                    offset={-80}
                    duration={500}
                    className="block px-4 py-2 text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 transition-colors text-sm"
                  >
                    {item.label}
                  </Link>
                ))}
              </div>
            )}
          </div>

          {/* Contact 드롭다운 */}
          <div
            className="relative inline-block"
            onMouseEnter={() => handleMouseEnter("contact")}
            onMouseLeave={handleMouseLeave}
          >
            <Link
              to="contact"
              spy={true}
              smooth={true}
              offset={-80}
              duration={500}
              className="cursor-pointer hover:text-indigo-500 transition-colors"
            >
              Contact
            </Link>
            {activeDropdown === "contact" && (
              <div className="absolute top-full left-0 mt-2 bg-white shadow-lg border border-gray-200 rounded-lg py-2 min-w-40 z-50">
                {dropdownItems.contact.map((item, index) => (
                  <Link
                    key={index}
                    to={item.to}
                    spy={true}
                    smooth={true}
                    offset={-80}
                    duration={500}
                    className="block px-4 py-2 text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 transition-colors text-sm"
                  >
                    {item.label}
                  </Link>
                ))}
              </div>
            )}
          </div>
        </nav>
      </div>
    </header>
  );
}