React使用map循环渲染列表时鼠标hover触发所有元素变更如何解决
问题原因
你当前使用的over/overEffect是父组件的全局公共状态,所有渲染出来的<li>元素都依赖同一个状态做显示判断,所以只要状态更新为true,所有列表项的判断条件都会同时生效,自然出现全部同步变化的问题。
解决方案
方案1:用状态存储当前悬停项的唯一标识(适合同一时间仅需要展示一个悬停项的场景)
把原来的布尔类型状态改成存储当前悬停项的id,渲染时判断当前项id和状态存储的id是否一致即可:
// 原状态声明修改:const [over, setOver] = useState(false) 改为下方写法 const [hoverId, setHoverId] = useState(null) // 列表渲染部分修改 {skillItems.map((item, index) => { const { id, name} = item; return ( <li key={id} className="singleChart" onMouseOver={() => setHoverId(id)} onMouseLeave={() => setHoverId(null)} >{hoverId === id ? name : ""}</li> })}
方案2:把列表项封装为独立子组件(适合每个项的悬停状态需要独立控制、互不影响的场景)
每个子组件自己维护内部的悬停状态,父组件不需要管理全局悬停状态:
// 单独封装的列表项子组件 const SkillItem = ({item}) => { const [isOver, setIsOver] = useState(false) const {name} = item return ( <li className="singleChart" onMouseOver={() => setIsOver(true)} onMouseLeave={() => setIsOver(false)} > {isOver ? name : ""} </li> ) } // 父组件渲染部分直接调用子组件即可 {skillItems.map((item) => ( <SkillItem key={item.id} item={item} /> ))}
内容的提问来源于stack exchange,提问作者Barry Allen
相关产品推荐
相关产品推荐

