我正在用React和Canvas制作一个绘图应用程序。但是,如果我将isMouseDown
变量设置为useState
而不是useRef
,画布就不能绘图,我似乎找不到原因。下面是组件:
function App() {
const [isMouseDown, setIsMouseDown] = useState(false);
const isMouseDownRef = useRef(false);
const canvasRef = useRef(null);
const ctx = useRef(null);
function triggerMouseDown() {
setIsMouseDown(true);
//isMouseDownRef.current = true;
}
function triggerMouseUp() {
setIsMouseDown(false);
//isMouseDownRef.current = false;
}
useEffect(() => {
if(canvasRef.current) {
ctx.current = canvasRef.current.getContext("2d");
canvasRef.current.width = 720;
canvasRef.current.height = 480;
canvasRef.current.addEventListener("mousemove", (e) => {
draw(
e.clientX - canvasRef.current.getBoundingClientRect().left,
e.clientY - canvasRef.current.getBoundingClientRect().top
)
})
canvasRef.current.addEventListener("mousedown", triggerMouseDown)
window.addEventListener("mouseup", triggerMouseUp)
}
return () => {
canvasRef.current.removeEventListener("mousedown", triggerMouseDown);
window.removeEventListener("mouseup", triggerMouseUp)
}
}, [])
function draw(x, y) {
if(isMouseDown) {
ctx.current.beginPath();
ctx.current.fillStyle = "blue";
ctx.current.arc(x, y, 20, 0, 2 * Math.PI);
ctx.current.stroke();
}
}
return (
<div className="App">
<canvas id="canvas1" ref={canvasRef}></canvas>
<h1>{JSON.stringify(isMouseDown)}</h1>
</div>
);
}
我知道它不应该是一个useState
,因为它会重新渲染太多,但我感兴趣的是为什么它不工作,特别是useState
。
2条答案
按热度按时间pdtvr36n1#
我在代码中做了一些更改:
第一个
zkure5ic2#
Y_T在this answer中的想法是正确的。不需要
useEffect
,但如果您 * 确实 * 使用useEffect
,它应该在捕获组中使用isMouseDown
,以便在适当的时间触发添加/删除移动侦听器。clearRect
是可选的。类似于(单击并拖动可绘制):但是,由于React提供了
onMouseMove
,我们可以直接使用它,而不是自己管理它:第一次