React中悬停单个列表项时所有项变色,如何仅让当前项变色?
修复React中链接悬停时全部变色的问题
问题根源
你所有未登录状态下的链接都共用同一个noUserColors状态变量,触发鼠标事件时会修改这个全局状态,导致所有绑定该状态的链接颜色同步变化,这就是悬停单个链接却全部变色的原因。
解决方案
方案1:使用CSS伪类(推荐)
内联样式无法直接处理:hover伪类,改用CSS类来控制样式,这是最简洁且符合React设计理念的方式:
- 定义CSS样式:
.unauthenticated-link { color: green; } .unauthenticated-link:hover { color: blue; }
- 修改组件代码:
const links = [ { link: 'Category 1' }, { link: 'Category 2' }, { link: 'Category 3' }, ]; function App() { const [currentUser, setCurrentUser] = useState(false); // 修正原代码拼写错误:setCurentUser → setCurrentUser return ( <> <ul> {links.map((link, index) => ( <li key={index}> {currentUser ? ( <a>{link.link}</a> {/* 登录状态下的链接样式可自行补充 */} ) : ( <a className="unauthenticated-link">{link.link}</a> )} </li> ))} </ul> </> ); }
方案2:给每个链接单独维护状态
将链接封装为独立子组件,每个子组件自己管理悬停状态,避免全局状态污染:
const links = [ { link: 'Category 1' }, { link: 'Category 2' }, { link: 'Category 3' }, ]; const UnauthenticatedLink = ({ text }) => { const [color, setColor] = useState('green'); return ( <a style={{ color }} onMouseEnter={() => setColor('blue')} onMouseLeave={() => setColor('green')} > {text} </a> ); }; function App() { const [currentUser, setCurrentUser] = useState(false); return ( <> <ul> {links.map((link, index) => ( <li key={index}> {currentUser ? ( <a>{link.link}</a> ) : ( <UnauthenticatedLink text={link.link} /> )} </li> ))} </ul> </> ); }
方案3:直接操作DOM元素样式
不使用状态,通过事件对象直接修改当前触发事件的链接样式:
const links = [ { link: 'Category 1' }, { link: 'Category 2' }, { link: 'Category 3' }, ]; function App() { const [currentUser, setCurrentUser] = useState(false); const handleMouseEnter = (e) => { e.target.style.color = 'blue'; }; const handleMouseLeave = (e) => { e.target.style.color = 'green'; }; return ( <> <ul> {links.map((link, index) => ( <li key={index}> {currentUser ? ( <a>{link.link}</a> ) : ( <a style={{ color: 'green' }} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > {link.link} </a> )} </li> ))} </ul> </> ); }
方案对比
- 方案1:代码最简洁,性能最优,样式与逻辑分离,优先推荐。
- 方案2:符合React组件化思想,适合需要给单个链接添加更多交互逻辑的场景。
- 方案3:直接操作DOM,虽然简单但不够React式,仅适合快速临时修复。
内容的提问来源于stack exchange,提问作者Don199
相关产品推荐
相关产品推荐

