我试图在React.js中创建一个非常简单的图形。实际上,我只是将我创建的Vanilla JS代码转换为React应用。 You can see the original code here on FiddleJS.
一切似乎都可以正常工作,但是渲染点的组件不会在道具更改时重新渲染。但是,它的道具正在改变(我在react-dev-tools中对其进行了检查)。我正在使用自定义事件侦听器,这可能是导致错误的原因吗?
import React, { useEffect, useState} from "react";
const addPoint = ({points, setPoints}) => (event) => {
const newPts = points;
newPts.push([event.pageX, event.pageY]);
setPoints(newPts);
};
const handleMouseDown = (pts) => (event) => {
console.log(pts.points);
document
.getElementById("drawing")!
.addEventListener("mousemove", handleMouseMove(pts));
};
const handleMouseUp = (pts) => (event) => {
document
.getElementById("drawing")!
.removeEventListener("mousemove", handleMouseMove(pts));
};
const handleMouseMove = (pts) => (event) => {
addPoint(pts) (event);
};
// Does not re-render when the props change
function RenderPoints(props) {
return (
<svg id="drawing" height="400" width="450">
<g id="points" stroke="black" strokeWidth="3" fill="black">
{props.points.map((point, index) => {
return <circle cx={point[0]} cy={point[1]} r="3" key={index}/>;
})}
</g>
</svg>
);
}
export default function Contact() {
useEffect(() => {
document
.getElementById("drawing")!
.addEventListener("mousedown", handleMouseDown({points, setPoints}));
document
.getElementById("drawing")!
.addEventListener("mouseup", handleMouseUp({points, setPoints}));
return () => {
document
.getElementById("drawing")!
.removeEventListener("mousedown", handleMouseDown({points, setPoints}));
document
.getElementById("drawing")!
.removeEventListener("mouseup", handleMouseUp({points, setPoints}));
};
});
const [points, setPoints] = useState([[100, 100]]);
return (
<>
<div>Draw</div>
<RenderPoints points={points} />
</>
);
}
答案 0 :(得分:0)
在addPoints
函数中,您正在将另一个元素推入相同的points
数组中。在比较数组和对象时,React会进行浅表比较,这意味着它不会深入探讨数组内容是否已更改-它只是检查状态变量(此处为points
)是否引用了同一数组或对象。另一种。
Array.prototype.push
不会创建新的数组,它只是将新元素推入同一数组中。因此,即使points
的内容发生了变化,points
仍然是同一数组。这就是为什么React不会重新渲染您的组件的原因。
要解决此问题,请执行以下操作,而不是将其压入同一数组中:
const newPts = [...points, [event.pageX, event.pageY]]
这将每次创建一个新数组,因此React现在将重新渲染您的组件。