React应用无法阻止事件冒泡,拖拽子组件时父组件也被拖动
解决React拖拽组件嵌套时父级跟随拖动的问题
问题描述
我开发了一个React应用,初始界面有一个按钮,点击该按钮会为现有div创建父级div。子div应能在其父div范围内拖拽,但当我尝试拖拽子组件时,其父组件也会被一同拖动。
现有代码问题分析
- 拖拽逻辑冲突:同时使用
react-draggable组件和自定义鼠标拖拽事件,两者触发逻辑重叠导致事件冒泡。 - 状态管理错误:直接将React元素存储在状态中,添加父级时重新构建整个嵌套结构,且无唯一
key导致组件识别异常。 - 边界与事件阻止不完整:未正确限制子组件拖拽的事件传播,且自定义逻辑未约束在父容器范围内。
修复方案
核心修改点
- 移除自定义拖拽逻辑,完全使用
react-draggable提供的功能 - 改用配置对象存储容器信息,通过递归渲染构建嵌套结构
- 确保拖拽事件阻止冒泡,添加唯一
key保证组件更新正确性
修复后完整代码
import React, { useState } from 'react'; import Draggable from 'react-draggable'; function DraggableBox({ w, h, children }) { return ( <Draggable bounds="parent" handle=".handle" onDrag={(e) => e.stopPropagation()}> <div style={{ position: 'relative', border: '1px solid black', width: `${w}px`, height: `${h}px`, overflow: 'hidden', }} > <div className="handle" style={{ height: 20, backgroundColor: 'gray', cursor: 'move', padding: '0 4px', lineHeight: '20px', }} > Title Bar </div> <div style={{ padding: '8px', height: `calc(100% - 20px)` }}> {children} </div> </div> </Draggable> ); } function App() { const [boxConfigs, setBoxConfigs] = useState([]); const [size, setSize] = useState(200); const handleAddParent = () => { setBoxConfigs(prev => [{ id: Date.now(), w: size, h: size, children: prev }]); setSize(prev => prev + 100); }; const renderBoxes = (configs) => { if (!configs.length) return null; return configs.map(config => ( <DraggableBox key={config.id} w={config.w} h={config.h} > {renderBoxes(config.children)} </DraggableBox> )); }; return ( <> <button onClick={handleAddParent}>Add Parent</button> <div style={{ height: '97vh', position: 'relative' }}> {renderBoxes(boxConfigs)} </div> </> ); } export default App;
修复说明
- 统一拖拽逻辑:完全依赖
react-draggable组件处理拖拽,避免自定义事件与第三方库冲突 - 配置化状态存储:用
boxConfigs存储容器的尺寸、唯一ID和子级配置,通过递归渲染构建嵌套结构,保证React组件识别的正确性 - 事件与边界处理:
onDrag中阻止事件冒泡,防止父容器响应子容器的拖拽操作;父容器设置overflow: hidden避免子元素溢出 - 唯一Key:为每个容器添加基于时间戳的唯一
key,确保React组件更新时的性能和稳定性
内容的提问来源于stack exchange,提问作者akkad
相关产品推荐
相关产品推荐

