单击时,将saveMouseDown
状态设置为1,释放后将其设置为0。
当我单击并移动鼠标时,我注销mouseDown
,即使鼠标按下也为0。但在屏幕上却显示1
import React, { useEffect, useRef, useState } from 'react';
const Home: React.FC = () => {
const [mouseDown, saveMouseDown] = useState(0);
const [canvasWidth, saveCanvasWidth] = useState(window.innerWidth);
const [canvasHeight, saveCanvasHeight] = useState(window.innerHeight);
const canvasRef = useRef<HTMLCanvasElement>(null);
let canvas: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D | null;
const addEventListeners = () => {
canvas.addEventListener('mousedown', (e) => { toggleMouseDown(); }, true);
canvas.addEventListener('mouseup', (e) => { toggleMouseUp(); }, true);
};
const toggleMouseDown = () => saveMouseDown(1);
const toggleMouseUp = () => saveMouseDown(0);
const printMouse = () => console.log(mouseDown);
// ^------ Why does this print the number 1 and the 2x 0 and then 1... and not just 1?
const removeEventListeners = () => {
canvas.removeEventListener('mousedown', toggleMouseDown);
canvas.removeEventListener('mouseup', toggleMouseUp);
};
useEffect(() => {
if (canvasRef.current) {
canvas = canvasRef.current;
ctx = canvas.getContext('2d');
addEventListeners();
}
return () => removeEventListeners();
}, []);
useEffect(() => {
if (canvasRef.current) {
canvas = canvasRef.current;
canvas.addEventListener('mousemove', (e) => { printMouse(); }, true );
}
return () => canvas.removeEventListener('mousemove', printMouse);
}, [mouseDown, printMouse]);
return (
<React.Fragment>
<p>Mouse Down: {mouseDown}</p>
{/* ^------ When this does print 1? */}
<canvas
id='canvas'
ref={canvasRef}
width={canvasWidth}
height={canvasHeight}
/>
</React.Fragment>
);
};
export { Home };
答案 0 :(得分:1)
在安装组件后,您只需添加一次移动侦听器,从而将初始mouseDown
值括起来。
尝试使用第二个useEffect
钩子来特定于 在mouseDown
状态更改时设置/更新onMouseMove事件侦听器。 remove eventListener需要指定相同的回调。
useEffect(() => {
if (canvasRef.current) {
canvas = canvasRef.current;
canvas.addEventListener('mousemove', printMouse, true );
}
return () => canvas.removeEventListener('mousemove', printMouse);;
}, [mouseDown, printMouse]);
将事件侦听器直接附加到canvas
元素上可能会更简单,那么您不必担心使用效果挂钩来处理封闭的过时状态。
<canvas
onMouseDown={() => setMouseDown(1)}
onMouseUp={() => setMouseDown(0)}
onMouseMove={printMouse}
width={canvasWidth}
height={canvasHeight}
/>