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

React中鼠标进出图片时state变量状态反转问题求助

问题排查与修复

核心问题1:初始状态设置错误

你把mouseOver的初始值设为了true,但页面加载时鼠标并没有悬停在图片上,这就导致初始状态和实际情况完全相反。当鼠标进入图片时,你把状态设为true(和初始值一致,看起来无变化),鼠标离开时设为false,最终呈现出和预期相反的效果。

核心问题2:DOM元素获取时机错误

你在组件顶层直接用document.getElementById("waldo-image")获取DOM元素,组件首次渲染时DOM还未挂载完成,此时myImg会是null,会导致FindPosition函数报错,间接影响后续逻辑执行。应该用React的useRef来安全获取DOM元素。

修复后的完整代码

import React, { useRef } from 'react'
import Waldo from '../images/waldo.jpg'

export default function Picture() {
    // 修正初始状态为false,匹配页面加载时的实际状态
    const [mouseOver, setMouseOver] = React.useState(false)
    const [clicked, setClicked] = React.useState(false)
    const [xPos, setXPos] = React.useState(0)
    const [yPos, setYPos] = React.useState(0)

    // 用useRef安全获取图片DOM元素
    const myImgRef = useRef(null)

    const changeMouseOverTrue = () => {
        setMouseOver(true)    
    }

    const changeMouseOverFalse = () => {
        setMouseOver(false)
    }

    function changeClick(){
        setClicked(prevClicked => !prevClicked)
        // 注意:setState是异步操作,此处直接console.log(clicked)会拿到旧值,需用useEffect监听查看新值
    }

    function FindPosition(oElement) {
        if (typeof (oElement.offsetParent) != "undefined") {
            for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
                posX += oElement.offsetLeft;
                posY += oElement.offsetTop;
            }
            return [posX, posY];
        }
        else {
            return [oElement.x, oElement.y];
        }
    }

    function GetCoordinates(e) {
        var PosX = 0;
        var PosY = 0;
        var ImgPos;
        // 通过ref.current获取DOM元素
        ImgPos = FindPosition(myImgRef.current);
        if (!e) var e = window.event;
        if (e.pageX || e.pageY) {
            PosX = e.pageX;
            PosY = e.pageY;
        }
        else if (e.clientX || e.clientY) {
            PosX = e.clientX + document.body.scrollLeft
                + document.documentElement.scrollLeft;
            PosY = e.clientY + document.body.scrollTop
                + document.documentElement.scrollTop;
        }
        let PositionX = PosX
        let PositionY = PosY
        PosX = PosX - ImgPos[0];
        PosY = PosY - ImgPos[1];

        setXPos(PositionX);
        setYPos(PositionY);
    }
    
    return (
        <div className="image-container">
            <img 
                src={Waldo} 
                className="waldo-image" 
                id="waldo-image"
                ref={myImgRef}
                onMouseLeave={changeMouseOverFalse}
                onMouseEnter={changeMouseOverTrue}
                onMouseDown={GetCoordinates}
                onClick={changeClick}
            />
            <div 
                className="dropdown-menu"
                style={clicked ? { display: 'flex', position: 'absolute', top: `${yPos}px`, left:`${xPos}px` } : {display:'none'}}
            >
                <button>Robin</button>
                <button>Fred Flinstone</button>
                <button>Johnny Test</button>
            </div>
        </div>
    )
}

额外提示

如果需要查看clicked的最新状态,可以添加useEffect监听:

React.useEffect(() => {
    console.log(clicked)
}, [clicked])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:55:04