React中点击图标时如何动态切换传入的props图标组件
点击切换MUI图标样式实现方案
核心逻辑:React中props是只读的,不能直接修改传入的Icon属性值,要通过状态驱动的方式,根据点击后的状态选择渲染填充/轮廓版本的图标。
结合YouTube侧边栏的实际交互(同一时间仅一个菜单项为激活填充态),推荐用父组件统一管理激活状态的方案,扩展性更好。
方案1:父组件统一管理选中态(适配侧边栏导航场景)
父组件改动
- 引入
useState存储当前激活的菜单项标识,默认选中首页 - 给侧边栏项传入激活态图标、未激活态图标、当前激活状态、点击回调
import { useState } from 'react'; import HomeIconfilled from '@mui/icons-material/Home'; import HomeIcon from '@mui/icons-material/HomeOutlined'; // 其他侧边栏菜单项的填充/轮廓图标按相同方式引入 function Sidebar() { // 存储当前选中的菜单项title,默认选中首页 const [activeMenu, setActiveMenu] = useState('Home'); return ( <div className="sidebar-wrapper"> <Sidebariconfunc ActiveIcon={HomeIconfilled} InactiveIcon={HomeIcon} Title="Home" isActive={activeMenu === 'Home'} onItemClick={() => setActiveMenu('Home')} /> {/* 其余菜单项(探索、订阅、库等)按相同格式传参即可 */} </div> ) }
改造自定义Sidebariconfunc组件
根据传入的激活状态判断渲染哪个图标,绑定点击事件触发父组件的状态更新
function Sidebariconfunc({ActiveIcon, InactiveIcon, Title, isActive, onItemClick}) { return ( <div className='SidebarRow' onClick={onItemClick} style={{ cursor: 'pointer' }} // 增加鼠标手型提示,交互更友好 > <div className='Sidebar_Icon'> {isActive ? <ActiveIcon /> : <InactiveIcon />} </div> <div className='Slidebar_Title'> {Title} </div> </div> ) }
这个方案的优势是点击其他菜单项时,之前激活的项会自动切回轮廓样式,不需要额外写重置逻辑,完全匹配真实YouTube的侧边栏交互。
方案2:组件内部自管理切换状态(适合独立开关类场景)
如果你不需要和其他菜单项联动,只需要点击单个图标时在填充/轮廓间来回切换,可以直接把状态放在组件内部,代码更精简:
import { useState } from 'react'; function Sidebariconfunc({ActiveIcon, InactiveIcon, Title}) { // 默认显示填充样式 const [isFilled, setIsFilled] = useState(true); return ( <div className='SidebarRow' onClick={() => setIsFilled(prevState => !prevState)} style={{ cursor: 'pointer' }} > <div className='Sidebar_Icon'> {isFilled ? <ActiveIcon /> : <InactiveIcon />} </div> <div className='Slidebar_Title'> {Title} </div> </div> ) }
组件调用方式:
<Sidebariconfunc ActiveIcon={HomeIconfilled} InactiveIcon={HomeIcon} Title="Home" />
注意:不要尝试直接修改传入的props值,React单向数据流规则下props是只读的,所有UI变化都必须通过状态更新触发重新渲染来实现。
内容的提问来源于stack exchange,提问作者Mohammad Dayarneh
相关产品推荐
相关产品推荐

