React中遍历元素时实现单个元素Hover效果的方案
React中map渲染卡片时悬停效果全局触发的解决方法
我在使用React的map函数渲染卡片列表时遇到了一个问题:鼠标悬停任意一张卡片,所有卡片都会触发悬停效果(显示“shop now”框),无法实现单张卡片独立的悬停交互。
原问题代码
const Card = () => { const [isHovering, setIsHovering] = useState(false); const handleMouseOver = () => { setIsHovering(true); }; const handleMouseOut = () => { setIsHovering(false); }; return ( <> {productsList.map((product) => ( <div key={product.id}> <div className="relative mb-4" onMouseOver={handleMouseOver} onMouseOut={handleMouseOut}> <img src={product.img} alt="product" className="w-fit h-fit jshover cursor-pointer" /> {isHovering ? <CardOptions /> : ""} </div> <div className="flex justify-center flex-col px-3"> <h3 className="captialize font-sans font-bold text-black mb-3">Adicolor Classics Joggers</h3> <div className="flex justify-between "> <span className="capitalize font-normal font-sans text-[#777777]">Dress</span> <span className="font-sans font-bold">$63.85</span> </div> </div> </div> ))} </> ) }
问题原因
原代码中使用了一个全局布尔状态isHovering,所有通过map生成的卡片都共享这个状态。当任意一张卡片触发onMouseOver时,状态被设置为true,导致所有卡片的{isHovering ? <CardOptions /> : ""}条件渲染都生效,最终所有卡片同时显示悬停元素。
解决方案
将状态改为存储当前悬停卡片的索引(初始值设为-1,表示无卡片悬停),通过索引匹配来实现单张卡片的独立悬停控制:
const Card = () => { const [isHovering, setIsHovering] = useState(-1); const handleMouseOver = (item) => { setIsHovering(item); }; const handleMouseOut = () => { setIsHovering(-1); }; return ( <> {productsList.map((product, index) => ( <div key={product.id}> <div className="relative mb-4" onMouseOver={() => { handleMouseOver(index); }} onMouseOut={handleMouseOut}> <img src={product.img} alt="product" className="w-fit h-fit jshover cursor-pointer" /> {isHovering === index ? <CardOptions /> : ""} </div> <div className="flex justify-center flex-col px-3"> <h3 className="captialize font-sans font-bold text-black mb-3">{product.title}</h3> <div className="flex justify-between "> <span className="capitalize font-normal font-sans text-[#777777]">{product.category}</span> <span className="font-sans font-bold">{product.price}</span> </div> </div> </div> ))} </> ) }
解决思路
- 将状态
isHovering的类型从布尔值改为数字,初始值设为-1(表示没有卡片处于悬停状态) - 在
map遍历卡片时,同时获取当前卡片的index - 鼠标悬停时,将当前卡片的
index存入状态;鼠标移出时,重置状态为-1 - 条件渲染时,仅当当前卡片的
index与状态中存储的索引匹配时,才显示悬停元素CardOptions
内容的提问来源于stack exchange,提问作者Hayytz
相关产品推荐
相关产品推荐

