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>
  );
};
→ Ссылка