从 React Js 中的 mousemove 事件侦听器触发的 HandleMouseMove 不使用更新状态
HandleMouseMove fired from mousemove event listener in React Js does not use updated state
什么有效:
当在触发器上触发反应 onMouseDown 事件时,我的状态变量“拖动”设置为 true。
此外,当 mouseUp 从经典事件侦听器在屏幕上的任何位置触发时,“拖动”设置为 false。
我的 mousemove 侦听器触发 handleMouseMove 函数。
什么不起作用:
handleMouseMove 检查拖动是否为真,如果为真,它应该打印“我正在拖动”,但看起来 handleMouseMove 永远不会变为真。 ????
如果拖动为真,如何让它工作并打印“我正在拖动”?
注:
使用每次拖动更改时都会触发的 useEffect 进行调试,确认事实上,只要反应 onMouseDown 和经典的 mouseup 事件触发,它就会正确地从 true 变为 false。
export const useDrag = () => {
const [dragging, setDragging] = useState(false);
useEffect(() => {
window.addEventListener("mousemove", handleMouseMove );
window.addEventListener("mouseup", handleMouseUp );
return () => {
window.removeEventListener("mousemove", handleMouseMove );
window.removeEventListener("mouseup", handleMouseUp);
};
}, []);
function handleMouseDown (e) {
e.stopPropagation();
e.preventDefault();
setDragging(true);
};
function handleMouseUp(e){
e.stopPropagation();
e.preventDefault();
setDragging(false);
}
function handleMouseMove(e){
if(dragging) console.log("I'm Dragging");
}
const bindTrigger = {
onMouseDown: handleMouseDown,
}
return [ bindTrigger ]
}
您在 useEffect
中绑定挂载的处理程序,但由于 useEffect
没有任何依赖项,因此在重新创建绑定函数时它不会更新它们(这发生在每个渲染器上)。所以对于处理程序,dragging
总是 false
.
当 dragging
为 true
时,您应该只将处理程序绑定到 window
。将 move
和 up
处理程序移动到 useEffect()
中,并使其依赖于 dragging
。如果 dragging
是 false
它只会调用清理函数来从 window
.
中删除处理程序
const { useState, useEffect } = React;
const useDrag = () => {
const [dragging, setDragging] = useState(false);
useEffect(() => {
if (!dragging) return;
function handleMouseMove(e) {
if (dragging) console.log("I'm Dragging");
}
function handleMouseUp(e) {
e.stopPropagation();
e.preventDefault();
setDragging(false);
}
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleMouseUp);
};
}, [dragging]);
function handleMouseDown(e) {
e.stopPropagation();
e.preventDefault();
setDragging(true);
};
const bindTrigger = {
onMouseDown: handleMouseDown,
}
return [bindTrigger];
}
const Demo = () => {
const [bindTrigger] = useDrag();
return (
<div {...bindTrigger}>Drag me</div>
);
}
ReactDOM.render(
<Demo />,
root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
什么有效: 当在触发器上触发反应 onMouseDown 事件时,我的状态变量“拖动”设置为 true。 此外,当 mouseUp 从经典事件侦听器在屏幕上的任何位置触发时,“拖动”设置为 false。 我的 mousemove 侦听器触发 handleMouseMove 函数。
什么不起作用: handleMouseMove 检查拖动是否为真,如果为真,它应该打印“我正在拖动”,但看起来 handleMouseMove 永远不会变为真。 ????
如果拖动为真,如何让它工作并打印“我正在拖动”?
注: 使用每次拖动更改时都会触发的 useEffect 进行调试,确认事实上,只要反应 onMouseDown 和经典的 mouseup 事件触发,它就会正确地从 true 变为 false。
export const useDrag = () => {
const [dragging, setDragging] = useState(false);
useEffect(() => {
window.addEventListener("mousemove", handleMouseMove );
window.addEventListener("mouseup", handleMouseUp );
return () => {
window.removeEventListener("mousemove", handleMouseMove );
window.removeEventListener("mouseup", handleMouseUp);
};
}, []);
function handleMouseDown (e) {
e.stopPropagation();
e.preventDefault();
setDragging(true);
};
function handleMouseUp(e){
e.stopPropagation();
e.preventDefault();
setDragging(false);
}
function handleMouseMove(e){
if(dragging) console.log("I'm Dragging");
}
const bindTrigger = {
onMouseDown: handleMouseDown,
}
return [ bindTrigger ]
}
您在 useEffect
中绑定挂载的处理程序,但由于 useEffect
没有任何依赖项,因此在重新创建绑定函数时它不会更新它们(这发生在每个渲染器上)。所以对于处理程序,dragging
总是 false
.
当 dragging
为 true
时,您应该只将处理程序绑定到 window
。将 move
和 up
处理程序移动到 useEffect()
中,并使其依赖于 dragging
。如果 dragging
是 false
它只会调用清理函数来从 window
.
const { useState, useEffect } = React;
const useDrag = () => {
const [dragging, setDragging] = useState(false);
useEffect(() => {
if (!dragging) return;
function handleMouseMove(e) {
if (dragging) console.log("I'm Dragging");
}
function handleMouseUp(e) {
e.stopPropagation();
e.preventDefault();
setDragging(false);
}
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleMouseUp);
};
}, [dragging]);
function handleMouseDown(e) {
e.stopPropagation();
e.preventDefault();
setDragging(true);
};
const bindTrigger = {
onMouseDown: handleMouseDown,
}
return [bindTrigger];
}
const Demo = () => {
const [bindTrigger] = useDrag();
return (
<div {...bindTrigger}>Drag me</div>
);
}
ReactDOM.render(
<Demo />,
root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>