我正在使用帶有 TypeScript 的 React,我試圖在畫布上繪制一個矩形形狀,該形狀是在畫布上繪制的,但在再次繪制后它進入了無限回圈。甚至我firstClicks, lastClicks在useEffect.
由于無限期運行,我的應用程式在一段時間后不斷崩潰。這是我的代碼:
import { useEffect, useRef, useState } from 'react';
interface ICoordinates{
x: number
y: number
}
const Canvas = ({height, width}: ICanvas) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const divRef = useRef<HTMLDivElement>(null);
let [firstClicks, setFirstClicks] = useState<ICoordinates>();
let [lastClicks, setLastClicks] = useState<ICoordinates>();
useEffect(() => {
const canvas = canvasRef.current?.getContext('2d');
const context = canvasRef.current;
let mousedown = false;
function drawRectangle(){
if(canvas){
canvas.beginPath();
if(firstClicks && lastClicks){
canvas.rect(firstClicks.x, firstClicks.y, lastClicks.x-firstClicks.x, lastClicks.y-firstClicks.y);
}
canvas.fillStyle = 'rgba(100,100,100,0.5)';
canvas.fill();
canvas.strokeStyle = "#df4b26";
canvas.lineWidth = 1;
canvas.stroke();
}
};
function redraw(){
if(context){
context.width = context.width;
}
drawRectangle();
};
if(context){
context.addEventListener("mousedown", function (e) {
setFirstClicks({
x: e.offsetX,
y: e.offsetY
})
mousedown = true;
});
context.addEventListener("mousemove", function (e) {
if (mousedown) {
setLastClicks({
x: e.offsetX,
y: e.offsetY
})
redraw();
}
});
context.addEventListener("mouseup", function (e) {
mousedown = false;
setLastClicks({
x: e.offsetX,
y: e.offsetY
})
});
context.addEventListener("mouseleave", function () {
mousedown = false;
});
}
},[firstClicks, lastClicks])
return (
<div ref={divRef}>
<canvas className='canvas' ref={canvasRef}>
</canvas>
</div>
)
}
export default Canvas
uj5u.com熱心網友回復:
你有沒有試過這個而沒有,[firstClicks, lastClicks]而是有一個空的依賴陣列:[]。
依賴陣列意味著這個useEffect回呼將在組件的安裝和卸載以及依賴陣列中變數的任何更改時運行。
我看到您正在使用setLastClicks并setFirstClicks表示一旦 this 被執行,useEffect 鉤子將檢測到firstClicksor 中的變化lastClick并再次運行該效果,從而導致無限回圈。
您可以通過console.log在setLastClicks和之前添加一個來仔細檢查setFirstClicks它,看看它是否在每次運行鉤子回呼時都改變狀態。
這是一個作業版本:
import { useEffect, useRef } from "react";
interface ICoordinates {
x: number;
y: number;
}
const Canvas = ({ height, width }: { height: number; width: number }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const divRef = useRef<HTMLDivElement>(null);
useEffect(() => {
console.log("Rerunning");
const canvas = canvasRef.current?.getContext("2d");
const context = canvasRef.current;
let mousedown = false;
let firstClick: ICoordinates = { x: 0, y: 0 };
let lastClick: ICoordinates = { x: 0, y: 0 };
function drawRectangle(
firstClicks: ICoordinates,
lastClicks: ICoordinates
) {
if (canvas) {
canvas.beginPath();
if (firstClicks && lastClicks) {
canvas.rect(
firstClicks.x,
firstClicks.y,
lastClicks.x - firstClicks.x,
lastClicks.y - firstClicks.y
);
}
canvas.fillStyle = "rgba(100,100,100,0.5)";
canvas.fill();
canvas.strokeStyle = "#df4b26";
canvas.lineWidth = 1;
canvas.stroke();
}
}
if (context) {
context.addEventListener("mousedown", function (e) {
firstClick = {
x: e.offsetX,
y: e.offsetY,
};
mousedown = true;
});
context.addEventListener("mousemove", function (e) {
if (mousedown) {
lastClick = {
x: e.offsetX,
y: e.offsetY,
};
drawRectangle(firstClick, lastClick);
}
});
context.addEventListener("mouseup", function (e) {
mousedown = false;
lastClick = {
x: e.offsetX,
y: e.offsetY,
};
});
context.addEventListener("mouseleave", function () {
mousedown = false;
});
}
}, []);
return (
<div ref={divRef}>
<canvas className="canvas" ref={canvasRef}></canvas>
</div>
);
};
export default Canvas;
繪制矩形 :D
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/396833.html
上一篇:從瀏覽器啟動Teams應用程式
下一篇:打字稿聯合型別不會引發錯誤
