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

React中onMouseOver随数据更新重复触发的问题解决

问题描述

我开发了一款在地图上实时绘制位置的React应用,位置约每秒更新一次。这些位置以SVG圆形元素呈现,我希望鼠标悬停时触发onMouseOver事件调用displayPilotName函数,但每次useEffect更新数据、刷新地图位置时,onMouseOver都会自动触发。调整interval间隔为3秒时,onMouseOver的触发频率也变为3秒一次。CSS的hover效果正常,但因需要调用函数无法满足需求,寻求解决该问题的方法。

相关代码:
SVG圆形元素:

const location = <circle
                     key={'serialNumber'}
                     cx={x}
                     cy={y}
                     r={4}
                     className="drone"
                     onMouseOver={displayPilotName('name')}
                   />

useEffect逻辑:

useEffect(() => {
  const interval = setInterval(() => {
    droneService.getAll().then(droneInfo =>
      setDrones(droneInfo)
    )
  }, 500)
  return () => clearInterval(interval)
}, [])
解决方案

核心问题

你当前的onMouseOver写法是直接执行函数,而非传递函数引用。每次组件渲染(包括useEffect更新数据导致的重渲染)时,displayPilotName('name')都会被立即调用,这就是它触发频率和interval同步的原因。

修复步骤

  1. 修改事件绑定方式
    用箭头函数包裹函数调用,确保只有鼠标悬停时才执行displayPilotName:
const location = <circle
                     key={serialNumber} // 注意:替换为每个无人机独有的标识变量,原固定字符串key会导致React无法正确追踪元素更新
                     cx={x}
                     cy={y}
                     r={4}
                     className="drone"
                     onMouseOver={() => displayPilotName('name')}
                   />

另外,原代码中key={'serialNumber'}是固定字符串,会让所有SVG圆形的key重复,React无法区分不同无人机元素,可能引发额外渲染问题,建议替换为真实的无人机唯一标识(比如serialNumber变量)。

  1. 可选:优化函数传递(避免重复创建函数)
    如果担心箭头函数每次渲染创建新实例影响性能,可以把displayPilotName改成返回函数的形式:
const displayPilotName = (name) => () => {
  // 原函数逻辑,比如显示飞行员名称
  console.log(name);
}

之后直接绑定即可:

onMouseOver={displayPilotName('name')}

这种方式和箭头函数效果一致,但不会每次渲染都生成新的函数实例。

原理说明

React事件属性需要接收函数引用,事件触发时才会执行该函数。你原来的写法是把displayPilotName('name')的执行结果传给事件,所以每次渲染都会先执行一遍函数,导致自动触发。而箭头函数或返回函数的方式,是把待执行的函数引用传给事件,只有鼠标悬停时才会调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:35:13