You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用无法阻止事件冒泡,拖拽子组件时父组件也被拖动

解决React拖拽组件嵌套时父级跟随拖动的问题

问题描述

我开发了一个React应用,初始界面有一个按钮,点击该按钮会为现有div创建父级div。子div应能在其父div范围内拖拽,但当我尝试拖拽子组件时,其父组件也会被一同拖动。

现有代码问题分析

  1. 拖拽逻辑冲突:同时使用react-draggable组件和自定义鼠标拖拽事件,两者触发逻辑重叠导致事件冒泡。
  2. 状态管理错误:直接将React元素存储在状态中,添加父级时重新构建整个嵌套结构,且无唯一key导致组件识别异常。
  3. 边界与事件阻止不完整:未正确限制子组件拖拽的事件传播,且自定义逻辑未约束在父容器范围内。

修复方案

核心修改点

  • 移除自定义拖拽逻辑,完全使用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;

修复说明

  1. 统一拖拽逻辑:完全依赖react-draggable组件处理拖拽,避免自定义事件与第三方库冲突
  2. 配置化状态存储:用boxConfigs存储容器的尺寸、唯一ID和子级配置,通过递归渲染构建嵌套结构,保证React组件识别的正确性
  3. 事件与边界处理:onDrag中阻止事件冒泡,防止父容器响应子容器的拖拽操作;父容器设置overflow: hidden避免子元素溢出
  4. 唯一Key:为每个容器添加基于时间戳的唯一key,确保React组件更新时的性能和稳定性

内容的提问来源于stack exchange,提问作者akkad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:37:34