在 React 组件中使用鼠标事件的事件处理程序时,如何让"useState"正常工作?



我正在尝试创建一个简单的"包装器";以使HTML元素";可拖动";。

我遇到的问题是;useState";变量CCD_ 1在事件处理程序CCD_。除了dragging未正确设置为true之外,事件处理程序mouseDownmouseUp似乎工作正常。

我做错了什么?我们非常感谢您的每一个建议或暗示!!!

附言:console.log('Dragging is set to true')console.log('Dragging is set to false')运行良好!就其理解而言,所有事件";火;正确地只是draggingmouseMove中总是假的。

import React, { useEffect, useState, useRef } from 'react';
interface Coordinate {
x: number;
y: number;
}
const SimpleDraggableWrapper = (props: any) => {
const [offset, setOffset] = useState<Coordinate | null>(null);
const [dragging, setDragging] = useState<boolean>(false);
const element = useRef<HTMLDivElement>(null);
const mouseDown = (event: React.MouseEvent) => {
if (element.current) {
setOffset({
x: event.clientX - element.current.offsetLeft,
y: event.clientY - element.current.offsetTop,
});
setDragging(true);
console.log('Dragging set to true');
}
};
const mouseUp = (event: MouseEvent) => {
setDragging(false);
console.log('Dragging set to false');
};
const mouseMove = (event: MouseEvent) => {
console.log(dragging);
if (dragging && element.current && offset) {
element.current.style.left = `${event.clientX - offset.x}px`;
element.current.style.top = `${event.clientY - offset.y}px`;
}
};
useEffect(() => {
document.addEventListener('mouseup', mouseUp);
document.addEventListener('mousemove', mouseMove);
return () => {
document.removeEventListener('mouseup', mouseUp);
document.removeEventListener('mousemove', mouseMove);
};
}, []);
return (
<div ref={element} onMouseDown={mouseDown}>
{React.cloneElement(props.children)}
</div>
);
};
export default SimpleDraggableWrapper;

这是一个与过时闭包有关的常见问题。

要了解更多信息,请检查:https://dmitripavlutin.com/react-hooks-stale-closures/.

您可以通过两种不同的方式解决此问题:

  1. 在useEffect依赖数组中添加拖动
useEffect(() => {
document.addEventListener('mouseup', mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp);
};
}, []);
useEffect(() => {
document.addEventListener('mousemove', mouseMove);
return () => {
document.removeEventListener('mousemove', mouseMove);
};
}, [dragging]);
  1. 在useCallback钩子中拖动鼠标移动的依赖数组,然后在useEffect依赖数组中添加mouseMouve函数
const mouseMove = useCallback((event: MouseEvent) => {
console.log(dragging);
if (dragging && element.current && offset) {
element.current.style.left = `${event.clientX - offset.x}px`;
element.current.style.top = `${event.clientY - offset.y}px`;
}
}, [dragging]);

useEffect(() => {
document.addEventListener('mouseup', mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp);
};
}, []);
useEffect(() => {
document.addEventListener('mousemove', mouseMove);
return () => {
document.removeEventListener('mousemove', mouseMove);
};
}, [mouseMove]);

最新更新