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
相关产品推荐
相关产品推荐

