You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:02:42