react-beautiful-dnd拖拽时draggable内iframe重载,如何阻止该问题?
问题原因
react-beautiful-dnd拖拽过程中iframe重渲染是浏览器原生特性+常见实现错误共同导致的:只要iframe节点被从DOM树中移除再重新插入,或者对应React组件被销毁重建,浏览器就会自动刷新iframe内容。
解决方案
- 第一步:修复Draggable的key配置
绝对不要使用数组下标作为<Draggable>的key值,拖拽排序后下标变化会导致React认为组件发生了变更,直接销毁重建整个模块,iframe自然会刷新。必须使用每个模块自身的固定唯一ID作为key:// 错误写法 {modules.map((mod, index) => <Draggable key={index} draggableId={mod.id} index={index}>...</Draggable>)} // 正确写法 {modules.map((mod, index) => <Draggable key={mod.id} draggableId={mod.id} index={index}>...</Draggable>)} - 第二步:使用React.memo缓存包含iframe的组件
把承载iframe的模块组件用React.memo包裹,自定义比较逻辑确保拖拽过程中props没有实际变更时,组件不会触发重渲染:const IframeModule = React.memo(({ src }) => { return <iframe src={src} frameBorder="0" /> }, (prevProps, nextProps) => { // 只有iframe地址变化时才重渲染组件 return prevProps.src === nextProps.src }) - 第三步:开启拖拽克隆模式避免原节点移动
配置react-beautiful-dnd拖拽时显示克隆的占位元素,原节点仅隐藏不移动、不摘除,从根源避免iframe节点被操作:- 给
<Draggable>开启shouldRenderCloneWhileDragging={true} - 拖拽激活状态下给原节点设置
visibility: hidden而非display: none,不要将其从DOM树中移除
- 给
- 第四步:拖拽过程中禁用iframe的事件响应
拖拽触发时给iframe添加pointer-events: none样式,避免iframe捕获鼠标事件干扰拖拽流程,拖拽结束后恢复样式即可。
内容的提问来源于stack exchange,提问作者user3284707
相关产品推荐
相关产品推荐

