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

如何避免子元素替换时onMouseEnter事件重复触发?

问题原因

点击切换国家时,父div内的子元素会被完全替换(比如<US>+<p>EN</p>换成<EG>+<p>AR</p>),触发组件重渲染。此时如果鼠标还停留在原图标位置,浏览器会把新挂载的图标识别成“新的悬停目标”,再次触发父元素的onMouseEnter事件,导致handleHover被重复调用,opacity又变回0.5。

解决方案

最直接可靠的方式是用CSS伪类替代JS事件控制悬停效果,彻底规避重渲染带来的事件重复触发问题:

  1. 删除JS里的handleHover、handleNoHover函数,以及languageButtonStyle中的opacity状态管理
  2. 给父div的CSS类header-right-side-language添加hover样式:
.header-right-side-language {
  opacity: 1;
  transition: opacity 0.2s; /* 可选,添加过渡动画提升体验 */
}

.header-right-side-language:hover {
  opacity: 0.5;
}
  1. 简化后的组件代码:
<div className="header-right-side-language"
     onClick={handleCountrySwitch}>
    {currentCountry === 'US' ?
        <>
            <US title="United States"/>
            <p>EN</p>
        </>
        : <>
            <EG title="Egypt"/>
            <p>AR</p>
        </>
    }
</div>
  1. 简化后的切换函数:
const handleCountrySwitch = () => {
    setCurrentCountry((prevCountry) => (prevCountry === 'US' ? 'EG' : 'US'));
};

如果必须保留JS控制逻辑(比如有复杂的悬停交互需求),可以用useRef记录鼠标状态:

import { useRef, useState } from 'react';

// ...

const isHoveringRef = useRef(false);
const [currentCountry, setCurrentCountry] = useState('US');
const [languageButtonStyle, setLanguageButtonStyle] = useState({ opacity: 1 });

const handleCountrySwitch = () => {
    setCurrentCountry((prevCountry) => (prevCountry === 'US' ? 'EG' : 'US'));
    // 仅当鼠标未悬停时重置opacity
    if (!isHoveringRef.current) {
        setLanguageButtonStyle((prevStyle) => ({ ...prevStyle, opacity: 1 }));
    }
};

const handleHover = () => {
    isHoveringRef.current = true;
    setLanguageButtonStyle((prevStyle) => ({ ...prevStyle, opacity: 0.5 }));
};

const handleNoHover = () => {
    isHoveringRef.current = false;
    setLanguageButtonStyle((prevStyle) => ({ ...prevStyle, opacity: 1 }));
};

通过isHoveringRef记录真实的悬停状态,重渲染后就不会错误触发重复的悬停逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:22:37