React中.map生成的多Div如何单独用useState实现鼠标悬停效果
解决React中.map生成组件的单个悬停状态控制问题
你遇到的核心问题是用单一布尔值状态控制了所有组件,导致鼠标事件触发时所有div的状态同步变化。以下是两种实用的解决思路:
方法一:用状态存储当前悬停项的唯一标识
无需拆分组件,只需将原布尔值状态改为存储当前悬停项的唯一ID(或其他唯一标识),通过ID匹配来控制单个组件的显示逻辑。
代码示例:
import { useState } from 'react'; function App() { // 模拟20条带唯一ID的列表数据 const items = Array.from({ length: 20 }, (_, idx) => ({ id: idx + 1, content: `项目${idx + 1}`, hoverContent: `项目${idx + 1}的悬停详情` })); // 存储当前悬停项的ID,初始为null表示无悬停状态 const [hoveredId, setHoveredId] = useState(null); return ( <div style={{ display: 'flex', flexWrap: 'wrap', gap: '10px', padding: '20px' }}> {items.map(item => ( <div key={item.id} // 必须用唯一ID作为key,禁止使用数组index onMouseEnter={() => setHoveredId(item.id)} onMouseLeave={() => setHoveredId(null)} style={{ width: '150px', border: '1px solid #eee', padding: '10px', borderRadius: '4px' }} > <p>{item.content}</p> {/* 仅当当前项ID与hoveredId匹配时,显示悬停内容 */} {hoveredId === item.id && <p style={{ color: '#2196F3', marginTop: '8px' }}>{item.hoverContent}</p>} </div> ))} </div> ); } export default App;
方法二:将单个项封装为独立组件
把每个div拆成独立子组件,让每个子组件自行管理悬停状态,各组件状态相互独立,不会互相干扰。
代码示例:
import { useState } from 'react'; // 独立子组件,自身维护悬停状态 function ItemCard({ content, hoverContent }) { const [isHovered, setIsHovered] = useState(false); return ( <div onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} style={{ width: '150px', border: '1px solid #eee', padding: '10px', borderRadius: '4px' }} > <p>{content}</p> {isHovered && <p style={{ color: '#2196F3', marginTop: '8px' }}>{hoverContent}</p>} </div> ); } function App() { const items = Array.from({ length: 20 }, (_, idx) => ({ id: idx + 1, content: `项目${idx + 1}`, hoverContent: `项目${idx + 1}的悬停详情` })); return ( <div style={{ display: 'flex', flexWrap: 'wrap', gap: '10px', padding: '20px' }}> {items.map(item => ( <ItemCard key={item.id} content={item.content} hoverContent={item.hoverContent} /> ))} </div> ); } export default App;
关键注意点:
- 两种方法都必须使用唯一标识(如ID)作为组件的
key,绝对不能用数组index,否则会因组件复用导致状态混乱。 - 如果你的原始数据没有天然唯一ID,可以手动生成(比如利用数据的唯一属性拼接,或使用
uuid库)。
内容的提问来源于stack exchange,提问作者BorisKlco
相关产品推荐
相关产品推荐

