Javascript react挂钩中的MouseMove事件侦听器:事件对象未定义或clientX/Y为空

Javascript react挂钩中的MouseMove事件侦听器:事件对象未定义或clientX/Y为空,javascript,reactjs,Javascript,Reactjs,我正在尝试将鼠标移动事件绑定到该对象。但不管我怎么做,要么e是空的,要么e.clientX和Y是空的 const App = (props) => { const [move, setMove] = useState({"ix": 0, "iy": 0}); const handleMove = (e) => { console.log(e); } return ( <div onMouseMove={hand

我正在尝试将鼠标移动事件绑定到该对象。但不管我怎么做,要么e是空的,要么e.clientX和Y是空的

const App = (props) => {
    const [move, setMove] = useState({"ix": 0, "iy": 0});

    const handleMove = (e) => {
        console.log(e);
    }

    return (
        <div onMouseMove={handleMove} width="500" height="500"></div> //e exists but clientX is null
        <div onMouseMove={() => handleMove()} width="500" height="500"></div> //e undefined 
    );
}
此外,我被这个警告淹没了,即使在阅读了提供的链接之后,我也不理解这个警告

警告:出于性能原因,将重用此合成事件。如果您看到这一点,那么您正在访问一个已发布/无效的合成事件的属性
pageY
。这被设置为null。如果必须保留原始合成事件,请使用event.persist()。有关更多信息,请参阅me/react事件池


你没有通过比赛

<div onMouseMove={(e) => handleMove(e)} width="500" height="500"></div>
handleMove(e)}width=“500”height=“500”>
//获取一个钩子函数
const{useState}=React;
函数App(){
const[move,setMove]=useState({ix:0,iy:0});
常量getMousePos=e=>{
返回{x:e.clientX,y:e.clientY};
};
常量handleMove=e=>{
console.log(getMousePos(e));
};
返回(
handleMove(e)}
样式={{背景颜色:“蓝色”,宽度:500,高度:500}
>
);
}
//渲染它
ReactDOM.render(
,
document.getElementById(“react”)
);

由于合成事件是池化的,因此在调用事件回调后,所有事件属性都将为空

但是,仍然可以访问事件属性,如:

const handleMove = (e) => {
  console.log(e) // nullified object
  console.log(e.clientX); // has value
}
或者使用
event.persist()
从池中删除此合成事件

const handleMove = (e) => {
  e.persist();
  console.log(e); // has value for clientX, etc
}

这里发生的情况是,您试图
console.log()
合成事件。而
React
会给你这个错误。这是完全合理的,正如
React
文档所述,原因如下:

出于性能原因,此合成事件被重用。如果您看到了这一点,那么您正在访问已发布/已取消的合成事件的属性页面。这被设置为null。如果必须保留原始合成事件,请使用event.persist()

因此,
React
重用合成事件对象。这就是为什么所有字段在每个事件处理程序的末尾都将为空。这就引出了经验法则:

您不能以异步方式访问合成事件对象

这就是
React
抱怨的原因,因为在合成事件为空后,您试图访问控制台中的合成事件对象。解决这个问题的方法是调用syntheticevent的
persist
函数来持久化所有字段,或者直接使用您需要的字段

    const handleMove = (e) => {
        console.log(e); // <~ will cause error to come up
        console.log(e.pageY) // <~ no error
    }

    const handleMovePersist = (e) => {
        e.persist()
        console.log(e) // <~ no error, because synthetic event is persisted
    }
const handleMove=(e)=>{

console.log(e);//这与onMouseMove={handleMove}的结果相同(提供了e,但clientX和Y为null)@Supertyp请参见上面的示例。是的,您的代码没有错,但我的问题不是事件没有传递,而是我无法访问整个e,我需要单独访问属性,否则它们都将被取消。顺便说一句,我刚刚尝试过,onMouseMove={handleMove}显然,这两种方法都可以使用。是的,这取决于如何传递函数,
{func}
{(e)=>func()e}
这两种方法都有效。啊,好吧,就是这样。因此,它不会出于性能原因提取属性,而是在我直接访问它们时提取属性,这就是警告的意思。对。因为合成事件是重复使用的。我使用
event.persist()添加了一种解决方法
仅供参考。请注意,v17+合成事件不再使用池,因此第二种情况不会影响任何内容。感谢您的澄清。e.persist()是否对性能有影响?@Supertyp由于持久化事件存储在其他地方(不再在事件池中),因此它有轻微的开销。最有可能的情况是,它不会,除非您在任何地方都使用
persist
。尽管如此,问题是您为什么需要存储整个事件?在几乎所有情况下,您最终仍然只使用事件中的少数字段(如果不是一个字段的话)。
    const handleMove = (e) => {
        console.log(e); // <~ will cause error to come up
        console.log(e.pageY) // <~ no error
    }

    const handleMovePersist = (e) => {
        e.persist()
        console.log(e) // <~ no error, because synthetic event is persisted
    }