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

React中useRef()结合onMouseOver修改div背景色失效问题

问题原因

你用单个useRef绑定到循环生成的所有<div>上,每次循环都会覆盖这个ref的指向,最终liItem.current只会指向最后一个生成的<div>元素。所以当你hover任意元素时,实际修改的是最后一个元素的背景色,而不是当前hover的那个,看起来就像样式没生效。

解决方案

有几种更简单的方式实现hover变色,完全不需要依赖useRef:

方法1:通过事件对象获取当前元素

修改onHover函数,利用事件参数e直接拿到触发hover的元素:

const onHover = (e) => {
  e.currentTarget.style.backgroundColor = 'cornflowerblue';
}

循环里的元素绑定事件无需额外修改,事件会自动传递参数:

<div key={county} style={liItemContainer} onMouseOver={onHover}>

如果需要鼠标移出时还原颜色,再添加一个onMouseOut事件:

const onMouseOut = (e) => {
  e.currentTarget.style.backgroundColor = '#a9c4f5';
}

// 绑定到元素上
<div key={county} style={liItemContainer} onMouseOver={onHover} onMouseOut={onMouseOut}>

方法2:使用CSS:hover伪类(推荐)

用CSS处理hover状态是最简洁高效的方式,还能自动处理鼠标移出的样式还原:

/* 可以在组件内添加style标签,或单独的CSS文件 */
.county-item {
  height: 50px;
  padding-left: 15px;
  display: flex;
  align-items: center;
  background-color: #a9c4f5;
}

.county-item:hover {
  background-color: cornflowerblue;
}

然后把元素的内联样式替换为className:

<div key={county} className="county-item">
  <li style={liStyle}>{county}</li>
</div>

方法3:React状态控制(适合复杂交互场景)

如果需要跟踪当前hover的元素做更多逻辑,可以用状态记录hover的区县名称,动态设置样式:

import React, { useState } from "react";

// ...其他代码不变
const [hoveredCounty, setHoveredCounty] = useState(null);

const onHover = (county) => {
  setHoveredCounty(county);
};

const onMouseOut = () => {
  setHoveredCounty(null);
};

// 循环时动态生成样式
let countiesListItems = counties.map(county => {
  const containerStyle = {
    ...liItemContainer,
    backgroundColor: hoveredCounty === county ? 'cornflowerblue' : liItemContainer.backgroundColor
  };
  return (
    <div 
      key={county} 
      style={containerStyle} 
      onMouseOver={() => onHover(county)}
      onMouseOut={onMouseOut}
    >
      <li style={liStyle}>{county}</li>
    </div>
  );
});
修复后的完整代码(方法1示例)
import React from "react";

const CountiesList = () => {
    const counties = [
        'Antrim',
        'Armagh',
        'Carlow',
        'Cavan',
        'Clare',
        'Cork',
        'Derry',
        'Donegal',
        'Down',
        'Dublin',
        'Fermanagh',
        'Galway',
        'Kerry',
        'Kildare',
        'Kilkenny',
        'Laois',
        'Leitrim',
        'Limerick',
        'Longford',
        'Louth',
        'Mayo',
        'Meath',
        'Monaghan',
        'Offaly',
        'Roscommon',
        'Sligo',
        'Tipperary',
        'Tyrone',
        'Waterford',
        'Westmeath',
        'Wexford',
        'Wicklow'
    ]
    
    const onHover = (e) => {
        e.currentTarget.style.backgroundColor = 'cornflowerblue'
    }

    const onMouseOut = (e) => {
        e.currentTarget.style.backgroundColor = '#a9c4f5'
    }
        
    const ulStyle = {
        listStyleType: 'none',
        paddingInlineStart: 0,
        margin: 0,
        width: '100%',
        height: '300px',
        overflowY: 'scroll',
        borderBottomLeftRadius: '12px'
    }
        
    const liItemContainer = {
        height: '50px',
        paddingLeft: '15px',
        display: 'flex',
        alignItems: 'center',
        backgroundColor: '#a9c4f5'
    }
        
    const liStyle = {
        fontWeight: '700'
    }
        
    let countiesListItems = counties.map(county => {
        return (
            <div key={county} style={liItemContainer} onMouseOver={onHover} onMouseOut={onMouseOut}>
                <li style={liStyle}>{county}</li>
            </div>
        )
    })
        
    return (
        <ul style={ulStyle}>
            {countiesListItems}
        </ul>
    )
}

export default CountiesList;

内容的提问来源于stack exchange,提问作者Brandon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 21:15:38