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

React图标点击状态切换:点击填充保持,切换恢复轮廓

解决方案

要实现点击图标切换填充/轮廓状态、切换时恢复原图标样式的效果,我们可以结合React Router的路由状态同步激活状态,确保刷新页面也能保持正确的图标样式。以下是修改后的代码:

import { Link, useLocation } from "react-router-dom";
import { AiOutlineHome, AiFillHome } from "react-icons/ai";
import { BsCalendarCheck, BsCalendarCheckFill } from "react-icons/bs";
import { BsCalendarPlus, BsCalendarPlusFill } from "react-icons/bs";
import "./FooterNav.css";

const FooterNav = () => {
  // 获取当前路由路径,同步激活状态
  const location = useLocation();

  // 导航配置数组,简化重复代码
  const navItems = [
    { path: "/", label: "Home", OutlineIcon: AiOutlineHome, FillIcon: AiFillHome },
    { path: "/past", label: "Past", OutlineIcon: BsCalendarCheck, FillIcon: BsCalendarCheckFill },
    { path: "/upcoming", label: "Upcoming", OutlineIcon: BsCalendarPlus, FillIcon: BsCalendarPlusFill },
  ];

  return (
    <div className="footer-nav-container">
      {navItems.map((item) => (
        <div className="footer-nav-icon" key={item.path}>
          <Link to={item.path}>
            {/* 根据当前路由判断渲染填充/轮廓图标 */}
            {location.pathname === item.path ? (
              <item.FillIcon className="active-icon" />
            ) : (
              <item.OutlineIcon />
            )}
            <p>{item.label}</p>
          </Link>
        </div>
      ))}
    </div>
  );
};

export default FooterNav;

关键说明

  • 路由状态同步:使用useLocation获取当前页面路径,确保图标状态与路由完全同步——无论是点击导航、刷新页面还是通过其他方式跳转,激活的图标都会自动匹配当前页面。
  • 简化代码结构:将导航项封装为数组,通过循环渲染避免重复代码,后续新增导航项只需在数组中添加配置即可。
  • 样式可选优化:可以给激活的图标添加active-icon类,在CSS中自定义颜色或大小,增强视觉反馈:
.active-icon {
  color: #your-active-color;
  /* 其他样式调整 */
}

如果不需要依赖路由状态,仅通过点击切换图标(刷新页面会重置状态),可以改用useState管理激活项:

import { useState } from "react";
import { Link } from "react-router-dom";
import { AiOutlineHome, AiFillHome } from "react-icons/ai";
import { BsCalendarCheck, BsCalendarCheckFill } from "react-icons/bs";
import { BsCalendarPlus, BsCalendarPlusFill } from "react-icons/bs";
import "./FooterNav.css";

const FooterNav = () => {
  const [activeTab, setActiveTab] = useState("/");

  const navItems = [
    { path: "/", label: "Home", OutlineIcon: AiOutlineHome, FillIcon: AiFillHome },
    { path: "/past", label: "Past", OutlineIcon: BsCalendarCheck, FillIcon: BsCalendarCheckFill },
    { path: "/upcoming", label: "Upcoming", OutlineIcon: BsCalendarPlus, FillIcon: BsCalendarPlusFill },
  ];

  return (
    <div className="footer-nav-container">
      {navItems.map((item) => (
        <div className="footer-nav-icon" key={item.path}>
          <Link 
            to={item.path} 
            onClick={() => setActiveTab(item.path)}
          >
            {activeTab === item.path ? (
              <item.FillIcon className="active-icon" />
            ) : (
              <item.OutlineIcon />
            )}
            <p>{item.label}</p>
          </Link>
        </div>
      ))}
    </div>
  );
};

export default FooterNav;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:07:48