React компонент потребляет много памяти
Я добился того, что мне нужно, но, кажется, этот компонент потребляет много памяти из-за событий mousemove.
Как я могу исправить эту ситуацию?
import { useEffect, useRef, useState } from "react";
import styled from "styled-components";
const StyledSSvgBlock = styled.div`
width: 300px;
height: 300px;
svg {
transform: rotate(45deg);
}
`;
const Slider = () => {
const [angle, setAngle] = useState(270);
const [track, setTrack] = useState(0);
const [x, setX] = useState(50);
const [y, setY] = useState(10);
const [isMouseDown, setIsMouseDown] = useState(false);
const svgBlockRef = useRef(null);
useEffect(() => {
const handleMouseMove = () => {
if (isMouseDown) {
const newX = 50 + 40 * Math.cos((angle * Math.PI) / 180);
const newY = 50 + 40 * Math.sin((angle * Math.PI) / 180);
setX(newX);
setY(newY);
setTrack(track + 0.7);
setAngle(angle + 1);
if (angle >= 540) {
setAngle(270);
}
if (track >= 188) {
setTrack(0);
}
}
};
const svgBlock = svgBlockRef.current;
const handleMouseDown = () => {
setIsMouseDown(true);
};
const handleMouseUp = () => {
setIsMouseDown(false);
};
if (svgBlock) {
svgBlock.addEventListener("mousedown", handleMouseDown);
svgBlock.addEventListener("mouseup", handleMouseUp);
svgBlock.addEventListener("mousemove", handleMouseMove);
}
}, [isMouseDown, angle, track]);
return (
<StyledSSvgBlock ref={svgBlockRef}>
<svg id="svg" width="50%" height="50%" viewBox="0 0 100 100">
<path
className="path"
fill="none"
strokeLinecap="round"
strokeWidth="5"
stroke="#6A8484"
strokeDasharray="200,230.2"
d={`M50 10 a 40 40 0 1 1 -40 40`}
></path>
<path
className="path"
fill="none"
strokeLinecap="round"
strokeWidth="2"
stroke="#c7872e"
strokeDasharray={`${track},230.2`}
d={`M50 10 a 40 40 0 1 1 -40 40`}
></path>
<circle className="circle" cx={x} cy={y} r="5" fill="black" />
</svg>
</StyledSSvgBlock>
);
};
export default Slider;
Ответы (1 шт):
Автор решения: SwaD
→ Ссылка
Необходимо убрать создание листнеров из useEffect.
Для этого, можно воспользоваться стандартными методами. Просто для компонента "создаем" нужные события.
От работы с DOM нативного JS в React приложении, надо отказаться полностью(иногда не всегда получается, но делать это надо осмысленно, когда других вариантов нет)
const Slider = () => {
const [angle, setAngle] = useState(270);
const [track, setTrack] = useState(0);
const [x, setX] = useState(50);
const [y, setY] = useState(10);
const [isMouseDown, setIsMouseDown] = useState(false);
const handleMouseMove = () => {
if (isMouseDown) {
const newX = 50 + 40 * Math.cos((angle * Math.PI) / 180);
const newY = 50 + 40 * Math.sin((angle * Math.PI) / 180);
setX(newX);
setY(newY);
setTrack(track + 0.7);
setAngle(angle + 1);
if (angle >= 540) {
setAngle(270);
}
if (track >= 188) {
setTrack(0);
}
}
};
const handleMouseDown = () => {
setIsMouseDown(true);
};
const handleMouseUp = () => {
setIsMouseDown(false);
};
return (
<StyledSSvgBlock onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp}>
<svg id="svg" width="50%" height="50%" viewBox="0 0 100 100">
<path
className="path"
fill="none"
strokeLinecap="round"
strokeWidth="5"
stroke="#6A8484"
strokeDasharray="200,230.2"
d={`M50 10 a 40 40 0 1 1 -40 40`}
></path>
<path
className="path"
fill="none"
strokeLinecap="round"
strokeWidth="2"
stroke="#c7872e"
strokeDasharray={`${track},230.2`}
d={`M50 10 a 40 40 0 1 1 -40 40`}
></path>
<circle className="circle" cx={x} cy={y} r="5" fill="black" />
</svg>
</StyledSSvgBlock>
);
};