Вместо ручного добавления и удаления , когда релевантно, напишите пользовательский хук useEvent
, который будет хранить обработчики от одного рендеринга к другому:
useEvent.js
import { useEffect, useRef } from "react";
export default function(event, handler, element=window) {
const savedHandler = useRef();
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
const eventListener = event => savedHandler.current(event);
element.addEventListener(event, eventListener);
return () => element.removeEventListener(event, eventListener);
}, [event, element]);
}
components/Dragon.js
useEvent("mousemove", onDrag);
useEvent("mouseup", onDragEnd);
Рабочая ручка: https://codesandbox.io/s/dragondrop-ceocx