https://codesandbox.io/s/compassionate-wilbur-6r1c3y?file=/src/App.tsx:0-1366
有人能解释一下为什么这条线不起作用吗?
"window.removeEventListener("mousemove",tellPos,false);"
我可以看到这个函数是在控制台中被调用的,所以我假设它并不像删除事件侦听器那样容易。
import { useState } from "react";
import "./styles.css";
export default function App() {
let [page, setPage] = useState({ pageX: 50, pageY: 50 });
let [string, setString] = useState(
"Position X : " + page.pageX + " Position Y : " + page.pageY
);
function tellPos(p: any) {
let page2: any = {};
page2.pageX = p.pageX - 50;
page2.pageY = p.pageY - 10;
setPage(page2);
setString("Position X : " + p.pageX + " Position Y : " + p.pageY);
}
function addListeners() {
console.log("fire add");
window.addEventListener("mousemove", tellPos, false);
}
function removeListeners() {
console.log("fire remove");
window.removeEventListener("mousemove", tellPos, false);
}
// let style = {position:"absolute", top:page.pageY+"px", left:page.pageX+"px"}
return (
<div
onClick={() => {
removeListeners();
}}
className="App"
>
<div
style={{
border: "1px solid black",
position: "absolute",
top: page.pageY + "px",
left: page.pageX + "px"
}}
onMouseEnter={() => {
addListeners();
}}
onClick={() => {
removeListeners();
}}
>
<h1>hover to move me</h1>
{string}
</div>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}发布于 2022-02-23 05:12:48
我想我看到了这里的问题:
在将tellPos绑定到mousemove时,每当鼠标被移动时,就会触发重呈现(即:重新执行App函数)(因为tellPos会触发状态更新,从而触发重呈现)。因为在呈现期间每次都定义tellPos、addListeners和removeListeners,因此指示removeListeners从window中删除与tellPos新实例匹配的事件处理程序,使在初始addListeners期间绑定的旧实例完好无损。
这个问题的解决方案似乎是避免在呈现过程中定义函数,特别是当这些函数被绑定为事件侦听器到后续呈现中未被替换的元素时。
我在呈现函数之外存储了一个带有tellPos的简单演示,显示了这个功能看起来像预期的那样:https://codesandbox.io/s/crimson-waterfall-xuzlb9?file=/src/App.tsx
https://stackoverflow.com/questions/71230900
复制相似问题