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

如何根据最后点击的项修改导航栏元素的底部边框样式?

导航栏选中状态修复方案

问题根源

每个NavButton子组件都维护着独立的selectedNavButton状态,彼此完全隔离。点击其中一个按钮时,只有该组件自身的状态会更新,其他按钮无法感知当前选中的是哪一项,导致无法实现「仅最后点击的选项显示底部边框」的需求。另外,setState是异步操作,你在handleNavButtonClick里立刻打印selectedNavButton得到的会是旧值,不过这不是核心问题。

修正方案:状态提升到父组件

把选中状态移到父组件Navbar中统一管理,所有子组件共享同一个状态源,这样就能确保只有最后点击的项被标记为选中。

修改后的父组件Navbar

const Navbar = () => {
  // 父组件统一维护选中的导航项
  const [selectedNav, setSelectedNav] = useState("");

  const handleNavClick = (navText) => {
    setSelectedNav(navText);
  };

  return (
    <nav className='navbar'>
      <motion.a className='logo' {...slideAnimation('left')}> some text </motion.a>
      <NavButton 
        textNavButton={"_hello"} 
        isSelected={selectedNav === "_hello"}
        onClick={() => handleNavClick("_hello")}
      />
      <NavButton 
        textNavButton={"_about-me"} 
        isSelected={selectedNav === "_about-me"}
        onClick={() => handleNavClick("_about-me")}
      />
    </nav>
  );
}

修改后的子组件NavButton

const NavButton = ({textNavButton, isSelected, onClick}) => {
  // 子组件不再维护状态,仅接收父组件传递的状态和点击事件
  return (
    <div>
        <a 
          className={`${isSelected ? "selectedLink" : "links"}`} 
          onClick={onClick}
        >
            {textNavButton} 
        </a>
    </div>
 )
}

优化CSS(可选)

可以减少重复样式,只保留差异部分:

.links{
    color:white;
    border-right: 1px solid rgb(73, 73, 73);
    padding: 20px 30px;
    font-size: 13px;
}
.selectedLink{
    composes: links; /* 继承links的所有样式 */
    border-bottom: 2px solid #d6b600;
}
/* 如果你的环境不支持`composes`,就写完整样式:
.selectedLink{
    color:white;
    border-right: 1px solid rgb(73, 73, 73);
    padding: 20px 30px;
    font-size: 13px;
    border-bottom: 2px solid #d6b600;
}
*/

进阶优化:循环渲染导航项

如果后续需要添加更多导航项,可以把导航数据抽成数组,通过循环渲染减少重复代码:

const Navbar = () => {
  const [selectedNav, setSelectedNav] = useState("");
  // 导航项数据集合
  const navItems = ["_hello", "_about-me"];

  const handleNavClick = (navText) => {
    setSelectedNav(navText);
  };

  return (
    <nav className='navbar'>
      <motion.a className='logo' {...slideAnimation('left')}> some text </motion.a>
      {navItems.map(item => (
        <NavButton 
          key={item}
          textNavButton={item} 
          isSelected={selectedNav === item}
          onClick={() => handleNavClick(item)}
        />
      ))}
    </nav>
  );
}

这样后续新增导航项,只需要在navItems数组里添加元素即可,无需重复编写NavButton代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:38:07