react高阶组件实现拖拽
实现拖拽功能的高阶组件
在React中,可以通过高阶组件(HOC)封装拖拽逻辑,使得被包裹的组件具备拖拽能力。以下是一个实现拖拽功能的HOC示例:
创建高阶组件
import React, { Component } from 'react';
const withDragAndDrop = (WrappedComponent) => {
return class extends Component {
state = {
isDragging: false,
position: { x: 0, y: 0 },
dragStart: { x: 0, y: 0 }
};
handleMouseDown = (e) => {
this.setState({
isDragging: true,
dragStart: {
x: e.clientX - this.state.position.x,
y: e.clientY - this.state.position.y
}
});
document.addEventListener('mousemove', this.handleMouseMove);
document.addEventListener('mouseup', this.handleMouseUp);
};
handleMouseMove = (e) => {
if (!this.state.isDragging) return;
this.setState({
position: {
x: e.clientX - this.state.dragStart.x,
y: e.clientY - this.state.dragStart.y
}
});
};
handleMouseUp = () => {
this.setState({ isDragging: false });
document.removeEventListener('mousemove', this.handleMouseMove);
document.removeEventListener('mouseup', this.handleMouseUp);
};
componentWillUnmount() {
document.removeEventListener('mousemove', this.handleMouseMove);
document.removeEventListener('mouseup', this.handleMouseUp);
}
render() {
const { position } = this.state;
return (
<div
style={{
position: 'absolute',
left: `${position.x}px`,
top: `${position.y}px`,
cursor: this.state.isDragging ? 'grabbing' : 'grab'
}}
onMouseDown={this.handleMouseDown}
>
<WrappedComponent {...this.props} />
</div>
);
}
};
};
使用高阶组件
const Box = () => {
return (
<div style={{
width: '100px',
height: '100px',
backgroundColor: 'blue'
}} />
);
};
const DraggableBox = withDragAndDrop(Box);
function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<DraggableBox />
</div>
);
}
export default App;
支持触摸事件
为了在移动设备上也能使用,可以添加触摸事件支持:

handleTouchStart = (e) => {
const touch = e.touches[0];
this.setState({
isDragging: true,
dragStart: {
x: touch.clientX - this.state.position.x,
y: touch.clientY - this.state.position.y
}
});
document.addEventListener('touchmove', this.handleTouchMove);
document.addEventListener('touchend', this.handleTouchEnd);
};
handleTouchMove = (e) => {
if (!this.state.isDragging) return;
const touch = e.touches[0];
this.setState({
position: {
x: touch.clientX - this.state.dragStart.x,
y: touch.clientY - this.state.dragStart.y
}
});
};
handleTouchEnd = () => {
this.setState({ isDragging: false });
document.removeEventListener('touchmove', this.handleTouchMove);
document.removeEventListener('touchend', this.handleTouchEnd);
};
然后在渲染方法中添加触摸事件处理器:

<div
// ...其他属性
onTouchStart={this.handleTouchStart}
>
<WrappedComponent {...this.props} />
</div>
性能优化
对于频繁的拖拽操作,可以使用requestAnimationFrame优化性能:
handleMouseMove = (e) => {
if (!this.state.isDragging) return;
requestAnimationFrame(() => {
this.setState({
position: {
x: e.clientX - this.state.dragStart.x,
y: e.clientY - this.state.dragStart.y
}
});
});
};
边界限制
可以添加边界限制,防止元素被拖出可视区域:
handleMouseMove = (e) => {
if (!this.state.isDragging) return;
let newX = e.clientX - this.state.dragStart.x;
let newY = e.clientY - this.state.dragStart.y;
// 限制在窗口范围内
newX = Math.max(0, Math.min(newX, window.innerWidth - 100));
newY = Math.max(0, Math.min(newY, window.innerHeight - 100));
this.setState({
position: { x: newX, y: newY }
});
};
这个高阶组件提供了基本的拖拽功能,可以根据需要进一步扩展,如添加拖拽限制、拖拽手柄或与其他组件的交互逻辑。






