React中实现点击后从0开始计数的鼠标X位置获取问题
React中实现点击后相对鼠标位置计算的问题修复
你的代码无法得到相对点击位置的坐标,核心原因是闭包陷阱:
useEffect的依赖数组为空,导致mouseMove和mouseClick函数仅在组件首次渲染时创建,它们捕获的startPosition始终是初始值0。即便你通过setStartPosition更新了状态,mouseMove里的startPosition依然是0,计算结果自然等于e.clientX。
下面提供两种可行的修复方案:
方案一:利用useCallback+更新useEffect依赖
通过useCallback包裹事件处理函数,并将它们加入useEffect的依赖数组,确保事件监听始终绑定最新的函数,从而获取到最新的状态值:
import React, { useState, useEffect, useCallback } from 'react'; const App = () => { const [startPosition, setStartPosition] = useState(0); const mouseMove = useCallback((e) => { console.log(e.clientX - startPosition); }, [startPosition]); const mouseClick = useCallback((e) => { setStartPosition(e.clientX); }, []); useEffect(() => { window.addEventListener("mousedown", mouseClick); window.addEventListener("mousemove", mouseMove); return () => { window.removeEventListener("mousedown", mouseClick); window.removeEventListener("mousemove", mouseMove); }; }, [mouseClick, mouseMove]); return <div className='App' />; }; export default App;
方案二:使用useRef避免闭包问题
如果不需要通过状态更新触发组件重渲染,推荐用useRef保存起始位置——它的.current属性是可变的,且不会被闭包固定住,能始终拿到最新值:
import React, { useEffect, useRef } from 'react'; const App = () => { const startPositionRef = useRef(0); const mouseMove = (e) => { console.log(e.clientX - startPositionRef.current); }; const mouseClick = (e) => { startPositionRef.current = e.clientX; }; useEffect(() => { window.addEventListener("mousedown", mouseClick); window.addEventListener("mousemove", mouseMove); return () => { window.removeEventListener("mousedown", mouseClick); window.removeEventListener("mousemove", mouseMove); }; }, []); return <div className='App' />; }; export default App;
内容的提问来源于stack exchange,提问作者niko
相关产品推荐
相关产品推荐

