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

如何用useRef()实现React导航项active类切换(替代jQuery)

解决React中Navbar激活项切换的问题

先看你原来的jQuery逻辑:点击#navbarSupportedContent下的li时,移除所有ul里li的active类,再给当前点击的li加上这个类。你用React的时候犯了几个典型错误——直接操作DOM不是React的核心思路,而且你的ref用法也有问题:同一个ref绑定多个li,最后只会指向最后一个元素,根本没法操作所有项。

正确的做法是用状态管理来控制激活状态,下面是完整的实现:

import { useState } from 'react';

function Navbar() {
  // 用状态存储当前激活的项标识,初始值设为"home"(对应Home项)
  const [activeTab, setActiveTab] = useState("home");

  // 点击处理函数,接收当前项的唯一标识
  const handleTabClick = (tabId) => {
    setActiveTab(tabId);
  };

  return (
    <div className="collapse navbar-collapse" id="navbarSupportedContent">
      <ul className="navbar-nav ml-auto">
        <div className="hori-selector">
          <div className="left"></div>
          <div className="right"></div>
        </div>
        {/* 每个li根据activeTab动态判断是否添加active类 */}
        <li className={`nav-item ${activeTab === "dashboard" ? "active" : ""}`}>
          <a 
            className="nav-link" 
            href="javascript:void(0);"
            onClick={() => handleTabClick("dashboard")}
          >
            <i className="fas fa-tachometer-alt"></i> Dashboard
          </a>
        </li>
        <li className={`nav-item ${activeTab === "home" ? "active" : ""}`}>
          <a 
            className="nav-link" 
            href="javascript:void(0);"
            onClick={() => handleTabClick("home")}
          >
            <i className="fas fa-house-user"></i> Home
          </a>
        </li>
        <li className={`nav-item ${activeTab === "components" ? "active" : ""}`}>
          <a 
            className="nav-link" 
            href="javascript:void(0);"
            onClick={() => handleTabClick("components")}
          >
            <i className="far fa-clone"></i> Components
          </a>
        </li>
        <li className={`nav-item ${activeTab === "calendar" ? "active" : ""}`}>
          <a 
            className="nav-link" 
            href="javascript:void(0);"
            onClick={() => handleTabClick("calendar")}
          >
            <i className="far fa-calendar-alt"></i> Calendar
          </a>
        </li>
      </ul>
    </div>
  );
}

export default Navbar;

关键说明:

  • 用useState创建activeTab状态,记录当前激活项的唯一标识(这里用字符串,你也可以用id或其他唯一值)
  • 每个li的className通过模板字符串动态生成:如果当前项的标识和activeTab匹配,就加上active类,否则不加
  • 给每个a标签绑定点击事件,点击时更新activeTab的值,React会自动重新渲染页面,更新对应的类名

如果你非要用DOM操作(不推荐,违背React声明式编程的设计理念),也可以修正你的代码:

import { useRef, useEffect } from 'react';

function Navbar() {
  const tabsContainerRef = useRef(null);

  useEffect(() => {
    const container = tabsContainerRef.current;
    if (!container) return;

    const handleClick = (e) => {
      // 找到点击的li元素(如果点击的是a标签,就取其父元素)
      const targetLi = e.target.closest('li.nav-item');
      if (!targetLi) return;

      // 移除所有li的active类
      const allLis = container.querySelectorAll('li.nav-item');
      allLis.forEach(li => li.classList.remove('active'));
      // 给当前点击的li加active类
      targetLi.classList.add('active');
    };

    container.addEventListener('click', handleClick);
    // 组件卸载时清理事件监听
    return () => container.removeEventListener('click', handleClick);
  }, []);

  return (
    <div className="collapse navbar-collapse" id="navbarSupportedContent" ref={tabsContainerRef}>
      <ul className="navbar-nav ml-auto">
        <div className="hori-selector">
          <div className="left"></div>
          <div className="right"></div>
        </div>
        <li className="nav-item">
          <a className="nav-link" href="javascript:void(0);">
            <i className="fas fa-tachometer-alt"></i> Dashboard
          </a>
        </li>
        <li className="nav-item active">
          <a className="nav-link" href="javascript:void(0);">
            <i className="fas fa-house-user"></i> Home
          </a>
        </li>
        <li className="nav-item">
          <a className="nav-link" href="javascript:void(0);">
            <i className="far fa-clone"></i> Components
          </a>
        </li>
        <li className="nav-item">
          <a className="nav-link" href="javascript:void(0);">
            <i className="far fa-calendar-alt"></i> Calendar
          </a>
        </li>
      </ul>
    </div>
  );
}

export default Navbar;

这个DOM操作版本用useEffect在组件挂载时添加事件监听,利用事件委托处理点击逻辑,但还是强烈建议用第一个状态管理的方案,更符合React的设计思想。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:11:52