You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何实现含组合CSS类的头部汉堡菜单切换?

移动端汉堡菜单在React中的实现问题

我尝试实现头部菜单的切换功能,但在浏览器运行React应用时出现了多个错误。原生JavaScript版本可以正常工作,但不知道如何在React中结合现有的CSS类动画(汉堡点击后变为X形)来实现,搜索资料后看到有人推荐useEffect或useState,但不清楚具体怎么用,希望得到解决建议。


现有CSS代码

@media screen and (max-width:800px) {
  .header__hamburger {
      display: block;
      position: fixed;
      top:30px;
      right: 20px;
  }

  .header__hamburger.active .header__hamburger-line:nth-child(2) {
     opacity: 0;
  }

  .header__hamburger.active .header__hamburger-line:nth-child(1) {
      transform: translateY(8px) rotate(45deg);
   }

   .header__hamburger.active .header__hamburger-line:nth-child(3) {
      transform: translateY(-8px) rotate(-45deg);
   }
}
@media screen and (max-width:800px) {
  .header__navcontainer {
      display: flex;
      margin-top: -400px;
      flex-direction: column;
      align-items: center;
      width: 75%;
      transition: 0.5s linear;
      opacity: 0;
  }

  .header__navcontainer.active {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 75%;
      transition: 0.5s linear;
      opacity: 1;
      margin-top: 0px;
  }
}

现有React组件代码

function AppHeader() {

    return (
        <header className={headerStyle.header}>
            <div className={headerStyle.header__content}>

                <nav className={headerStyle.header__navbar}>
                    <a>
                        <img className={headerStyle.header__logo} src={Logo} alt="Logo" />
                    </a>

                    <div className={headerStyle.header__hamburger}>
                        <span className={headerStyle.header__hamburgerline}></span>
                        <span className={headerStyle.header__hamburgerline}></span>
                        <span className={headerStyle.header__hamburgerline}></span>
                    </div>

                    <div className={headerStyle.header__navcontainer}>
                        <ul className={headerStyle.header__linkscontainer}>
                          ... 
                        </ul>
                    </div>
                </nav>

            </div>
        </header>
    );
}

export default AppHeader;

可正常工作的原生JavaScript代码

const hamburger = document.getElementsByClassName('header__hamburger')[0];
const navMenu = document.getElementsByClassName('header__nav-container')[0];

hamburger.addEventListener('click', () => {
    navMenu.classList.toggle('active')
    hamburger.classList.toggle('active')
});

document.querySelectorAll(".header__link").forEach(n => n.addEventListener("click", () => {
    navMenu.classList.remove('active')
    hamburger.classList.remove('active')
}));

解决方案:用useState管理菜单激活状态

在React里不用直接操作DOM,靠状态驱动视图更新就行,用useState就能实现类的切换,步骤如下:

  1. 先引入useState Hook:
import { useState } from 'react';
  1. 在组件内部定义状态和对应的操作函数:
function AppHeader() {
  // 用isMenuActive记录菜单是否激活,初始为false(未激活)
  const [isMenuActive, setIsMenuActive] = useState(false);

  // 切换菜单状态的函数
  const toggleMenu = () => {
    setIsMenuActive(!isMenuActive);
  };

  // 关闭菜单的函数(点击导航链接时调用)
  const closeMenu = () => {
    setIsMenuActive(false);
  };
  1. 动态拼接className,根据状态决定是否添加active类:
  • 汉堡按钮的类名:${headerStyle.header__hamburger} ${isMenuActive ? 'active' : ''}
  • 导航容器的类名:${headerStyle.header__navcontainer} ${isMenuActive ? 'active' : ''}
  1. 给元素绑定点击事件:
  • 汉堡按钮绑定toggleMenu函数,点击切换状态
  • 每个导航链接绑定closeMenu函数,点击后关闭菜单
  1. 完整的组件代码:
import { useState } from 'react';
import Logo from './path-to-your-logo'; // 替换成你的Logo路径
import headerStyle from './path-to-your-styles'; // 替换成你的样式文件路径

function AppHeader() {
  const [isMenuActive, setIsMenuActive] = useState(false);

  const toggleMenu = () => {
    setIsMenuActive(!isMenuActive);
  };

  const closeMenu = () => {
    setIsMenuActive(false);
  };

  return (
    <header className={headerStyle.header}>
      <div className={headerStyle.header__content}>
        <nav className={headerStyle.header__navbar}>
          <a>
            <img className={headerStyle.header__logo} src={Logo} alt="Logo" />
          </a>

          <div 
            className={`${headerStyle.header__hamburger} ${isMenuActive ? 'active' : ''}`}
            onClick={toggleMenu}
          >
            <span className={headerStyle.header__hamburgerline}></span>
            <span className={headerStyle.header__hamburgerline}></span>
            <span className={headerStyle.header__hamburgerline}></span>
          </div>

          <div className={`${headerStyle.header__navcontainer} ${isMenuActive ? 'active' : ''}`}>
            <ul className={headerStyle.header__linkscontainer}>
              {/* 示例导航链接,根据你的实际情况修改 */}
              <li>
                <a className={headerStyle.header__link} onClick={closeMenu}>首页</a>
              </li>
              <li>
                <a className={headerStyle.header__link} onClick={closeMenu}>关于我们</a>
              </li>
              <li>
                <a className={headerStyle.header__link} onClick={closeMenu}>服务</a>
              </li>
            </ul>
          </div>
        </nav>
      </div>
    </header>
  );
}

export default AppHeader;

补充说明

这里不需要用useEffect,因为我们不需要处理DOM监听、数据请求这类副作用,只是单纯通过状态变化来控制CSS类的显示,useState完全能满足需求,而且更符合React的状态驱动思想。


内容的提问来源于stack exchange,提问作者Vladimiro Antipin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:25:11