我在一个项目中使用 React 和 TypeScript,最近拼凑了以下钩子:
export const useDrag = (selectionRef: React.MutableRefObject<HTMLDivElement>) => {
const [dragStart, setDragStart] = useState<Coordinates>(null);
const [dragEnd, setDragEnd] = useState<Coordinates>(null);
const onMouseDown = (e: MouseEvent) => setDragStart(getMouseOffset(e, selectionRef.current));
const onMouseUp = () => {
setDragStart(null);
setDragEnd(null);
};
const onMouseMove = (e: any) => {
if (dragStart) {
setDragEnd(getMouseOffset(e, selectionRef.current));
}
};
useEffect(() => {
const current = selectionRef.current;
if (current) {
current.addEventListener('mousedown', onMouseDown);
current.addEventListener('mouseup', onMouseUp);
current.addEventListener('mousemove', onMouseMove);
return () => {
current.removeEventListener('mousedown', onMouseDown);
current.removeEventListener('mouseup', onMouseUp);
current.removeEventListener('mousemove', onMouseMove);
};
}
}, [selectionRef, dragStart]);
return {
pendingSelection: dragStart && dragEnd && { start: dragStart, end: dragEnd },
};
};
这几乎按预期工作。问题是当我在另一个组件中使用这个钩子时:
...
const selectionRef = useRef<HTMLDivElement>();
const { pendingSelection } = useDrag(selectionRef);
return (
<div className="selection" ref={selectionRef}></div>
{pendingSelection && (
<div
style={{
height: pendingSelection.end.y - pendingSelection.start.y,
width: pendingSelection.end.x - pendingSelection.start.x,
}}
></div>
);
...
似乎 'mousemove' 事件发生得如此频繁,以至于实际上减慢了渲染过程(以至于暂时冻结了页面)。
我见过处理拖拽事件的 React 包,更新非常流畅。我知道我可以切换到其中之一,但真的更想了解我在这里做错了什么,并避免对如此小的用例产生依赖性。
很乐意提供更多代码或工作示例。任何信息表示赞赏!