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

React实现Header导航点击后仅当前选中链接文字变色

问题描述

近期刚开始学习编程,正在搭建个人作品集网站。开发Header导航模块时,想要实现的交互效果为:点击导航链接时,仅当前被点击的链接文字变为红色;点击其他导航链接时,之前变红的链接恢复为默认灰色,始终保持只有最新点击的链接为红色高亮状态。
目前遇到的问题:点击某链接后文字变红,但点击其他链接时,之前点击的链接仍然保持红色,无法恢复默认颜色,出现多个链接同时高亮的错误效果。
问题效果截图
效果示例:

  • 正确效果:home about work skill contact(仅about高亮)
  • 错误效果:home about work skill contact(多个链接同时高亮)
    技术栈为React、Tailwind CSS,配合react-scroll实现平滑滚动,原有代码如下:

Header.jsx 原有代码

import React, { useState } from "react";
import { Link as ScrollLink } from "react-scroll";

const Header = (props) => {
  const { headerPage } = props;
  const [onClickChangeColor, setOnClickChangeColor] = useState(false);
  const redText = () => {
    setOnClickChangeColor(!onClickChangeColor);
  };

  return (
    <div class="mr-8 cursor-pointer">
      <ScrollLink
        className={onClickChangeColor ? "text-[#FF5757]" : ""}
        onClick={redText}
        to={headerPage}
        smooth={true}
        duration={500}
      >
        {headerPage}
      </ScrollLink>
    </div>
  );
};

export default Header;

HeaderLayout.jsx 原有代码

import React from "react";
import Header from "./Header";

const HeaderLayout = () => {
  const headerPages = ["home", "about", "work", "skill", "contact"];

  return (
    <div class="sticky top-0 flex justify-end h-20 text-md pt-10 mr-10 text-center bg-[#292929]">
      {headerPages.map((headerPage) => (
        <Header headerPage={headerPage}>{headerPage}</Header>
      ))}

      <div
        className="resume"
        class="w-24 h-8  text-[#FF5757] border border-[#FF5757] rounded-md"
      >
        <a
          href="https://drive.google.com/file/d/usp=sharing"
          class="block"
        >
          resume
        </a>
      </div>
    </div>
  );
};

export default HeaderLayout;

问题根源

每个导航项单独封装的Header组件都维护了独立的本地状态,点击链接时只会切换当前组件自身的高亮标记,其他导航组件的状态不会被同步重置,因此会出现多个链接同时保持红色高亮的错误效果。

修复方案

将高亮状态统一提升到父组件HeaderLayout管理,只存储当前激活的导航项标识,而非每个子组件各自维护独立的布尔值,即可保证同一时间只有一个匹配的导航项高亮。

1. 修改父组件 HeaderLayout.jsx

  • 新增状态存储当前激活的导航名,默认可设为home
  • 遍历渲染导航项时,把「当前激活项判断标识」和「点击修改激活项的回调」传给子组件
  • 修正原代码中React混用class/className的语法错误(React中DOM属性需要用className代替原生class)
    修改后代码:
import React, { useState } from "react";
import Header from "./Header";

const HeaderLayout = () => {
  const headerPages = ["home", "about", "work", "skill", "contact"];
  // 统一管理全局激活的导航项
  const [activePage, setActivePage] = useState("home");

  return (
    <div className="sticky top-0 flex justify-end h-20 text-md pt-10 mr-10 text-center bg-[#292929]">
      {headerPages.map((headerPage) => (
        <Header 
          key={headerPage}
          headerPage={headerPage}
          isActive={activePage === headerPage}
          onActiveChange={() => setActivePage(headerPage)}
        />
      ))}

      <div className="resume w-24 h-8 text-[#FF5757] border border-[#FF5757] rounded-md">
        <a
          href="https://drive.google.com/file/d/usp=sharing"
          className="block"
        >
          resume
        </a>
      </div>
    </div>
  );
};

export default HeaderLayout;

2. 修改子组件 Header.jsx

  • 删除组件内部独立的onClickChangeColor本地状态
  • 接收父组件传入的isActive和onActiveChange属性,直接根据isActive判断是否应用高亮样式,点击时触发父组件传入的回调更新全局激活项
    修改后代码:
import React from "react";
import { Link as ScrollLink } from "react-scroll";

const Header = (props) => {
  const { headerPage, isActive, onActiveChange } = props;

  return (
    <div className="mr-8 cursor-pointer text-gray-400">
      <ScrollLink
        className={isActive ? "text-[#FF5757]" : ""}
        onClick={onActiveChange}
        to={headerPage}
        smooth={true}
        duration={500}
      >
        {headerPage}
      </ScrollLink>
    </div>
  );
};

export default Header;

可选优化方案

react-scroll的ScrollLink组件原生支持activeClass属性,开启滚动监听后,会自动在页面滚动到对应区块时给链接添加激活类名,无需手动维护点击状态,示例写法:

<ScrollLink
  activeClass="text-[#FF5757]"
  to={headerPage}
  smooth={true}
  duration={500}
  spy={true}
>
  {headerPage}
</ScrollLink>

这种写法不仅点击时会触发高亮,页面手动滚动到对应区块时也会自动同步导航高亮状态,交互体验更流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:39:16