Dnd Kit与Re-Resizable联用异常:Resize事件无法触发
解决Dnd Kit与Re-Resizable组件事件冲突问题
问题根源
你的代码存在两个核心冲突点:
- 父级Draggable容器的
onPointerDown事件中,调用Dnd Kit的listeners.onPointerDown后执行了e.preventDefault()/e.stopPropagation(),直接拦截了Re-Resizable手柄的事件触发。 - 容器同时使用
top/left和transform定位,导致Re-Resizable的尺寸计算逻辑混乱,手柄实际可点击区域与视觉位置不匹配。
解决方案
1. 统一容器定位逻辑
移除top和left样式,仅用transform叠加位移,避免布局计算冲突:
<div {...listeners} {...attributes} ref={setNodeRef} className="draggable" style={{ width, height, position: "absolute", backgroundColor: "white", border: `1px solid ${activeElement === id ? "#0984e3" : "black"}`, // 合并基础位移与Dnd Kit的transform位移 transform: `translate3d(${x + (transform?.x || 0)}px, ${y + (transform?.y || 0)}px, 0)`, }} // ...其他属性 >
2. 区分拖拽与Resize手柄事件
在容器的onPointerDown中,判断点击目标是否为Re-Resizable的手柄(默认类名为react-resizable-handle),仅在非手柄区域触发Dnd Kit的拖拽逻辑:
onPointerDown={(e) => { setActiveElement(id); // 检测是否点击了Resize手柄 const isResizeHandle = e.target.closest('.react-resizable-handle'); // 仅非手柄区域触发Dnd拖拽 if (!isResizeHandle && listeners?.onPointerDown) { listeners.onPointerDown(e); // 移除不必要的preventDefault/stopPropagation,避免影响子元素事件 } }}
3. 修复Resizable组件配置
添加最小尺寸保证手柄可交互,移除事件中不必要的拦截逻辑,并补充内部内容:
<Resizable size={{ width, height }} minWidth={50} minHeight={50} onResize={() => console.log("on resize")} onResizeStart={(e) => { console.log("resize start"); // 移除e.preventDefault()和e.stopPropagation(),避免事件被拦截 }} onResizeStop={(e, direction, ref, delta) => { console.log("on resize stop"); // 更新元素尺寸状态 setWidth(prev => prev + delta.width); setHeight(prev => prev + delta.height); }} > {/* 必须添加内部元素,保证Resizable有可识别的尺寸范围 */} <div style={{ width: '100%', height: '100%' }}></div> </Resizable>
4. 额外注意事项
- 确保Re-Resizable的样式正确加载,手柄的
z-index高于容器,避免被遮挡。 - 如果使用Dnd Kit的
Sortable或其他高阶组件,需确保拖拽状态不会影响Resizable的事件响应。
内容的提问来源于stack exchange,提问作者Maximiliano Bisurgi
相关产品推荐
相关产品推荐

