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
相关产品推荐
相关产品推荐

