在 React 中操作 DOM 元素时,使用 document.querySelector
以及全局事件监听(如 addEventListener
)并不推荐,因为这些方法无法与 React 的生命周期很好地协调,可能会导致内存泄漏或影响性能。
可以改为使用 useRef
和 useEffect
来处理 DOM 元素以及事件监听。
React 代码:
javascript
import React, { useRef, useEffect, useState } from 'react';
import styles from './index.module.less';
const ComponentName = () => {
const containerRef = useRef(null);
const leftPanelRef = useRef(null);
const rightPanelRef = useRef(null);
const dividerRef = useRef(null);
const [isDragging, setIsDragging] = useState(false);
useEffect(() => {
const handleMouseDown = () => {
setIsDragging(true);
};
const handleMouseMove = (e) => {
if (!isDragging) return;
const containerRect = containerRef.current.getBoundingClientRect();
const offsetX = e.clientX - containerRect.left;
const leftWidth = (offsetX / containerRect.width) * 100;
const rightWidth = 100 - leftWidth;
leftPanelRef.current.style.width = `${leftWidth}%`;
rightPanelRef.current.style.width = `${rightWidth}%`;
};
const handleMouseUp = () => {
setIsDragging(false);
};
const divider = dividerRef.current;
divider.addEventListener('mousedown', handleMouseDown);
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
// 清理事件监听器
return () => {
divider.removeEventListener('mousedown', handleMouseDown);
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
}, [isDragging]);
return (
<div className={styles.container} ref={containerRef}>
<div className={styles.leftPanel} ref={leftPanelRef}></div>
<div className={styles.divider} ref={dividerRef}></div>
<div className={styles.rightPanel} ref={rightPanelRef}></div>
</div>
);
};
export default ComponentName;
样式css:
javascript
.container {
display: flex;
width: 100%;
height: 100vh;
position: relative;
}
.leftPanel {
width: 50%;
background-color: lightblue;
}
.rightPanel {
width: 50%;
background-color: lightgreen;
}
.divider {
width: 5px;
background-color: gray;
cursor: ew-resize;
position: relative;
}
注释:
useRef
:用来获取 DOM 元素引用,如containerRef
、leftPanelRef
、rightPanelRef
和dividerRef
。useState
:用来存储拖动的状态isDragging
。useEffect
:用于在组件挂载时添加事件监听器,并在组件卸载时清理这些监听器。这样可以避免内存泄漏或重复监听。- 清理事件 :确保在组件卸载时移除
mousemove
和mouseup
的事件监听,避免意外行为。 getBoundingClientRect()
是 JavaScript 中用于获取元素的边界信息的方法。它返回一个DOMRect
对象,包含该元素相对于视口的位置和大小信息,包括top
,right
,bottom
,left
,width
, 和height
等属性。