拖动后TinyMCE编辑器iframe失效,React+@dnd-kit/sortable求助
解决React + @dnd-kit/sortable 拖动后TinyMCE编辑器失效的问题
拖动后TinyMCE编辑器iframe空白、工具栏失效,本质是@dnd-kit拖动过程中会修改DOM结构(比如将节点移到临时容器),导致TinyMCE的iframe与原DOM节点的绑定关系断裂,编辑器实例无法正常工作。以下是可行的解决思路:
核心方案:拖动结束后重建编辑器实例并恢复内容
通过触发组件重新挂载彻底重建编辑器,同时结合状态管理保存/恢复内容,步骤如下:
- 维护每个编辑器的内容状态
在父组件中为每个编辑器维护独立的内容状态,确保内容实时同步:
const [editorContents, setEditorContents] = useState({ editor_0: '初始内容1', editor_1: '初始内容2', // 更多编辑器... }); const updateEditorContent = (editorId, newContent) => { setEditorContents(prev => ({ ...prev, [editorId]: newContent })); };
- 给编辑器组件加动态Key,触发重新挂载
父组件维护一个editorKeys状态,拖动结束后更新对应编辑器的Key,强制组件卸载并重新挂载:
const [editorKeys, setEditorKeys] = useState( Object.keys(editorContents).reduce((acc, id) => { acc[id] = Date.now(); return acc; }, {}) );
- 在SortableItem中监听拖动结束事件
利用@dnd-kit的useSortable钩子,在拖动结束时更新对应编辑器的Key:
const SortableEditorItem = ({ editorId }) => { const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: editorId }); const handleDragEnd = () => { // 更新Key触发编辑器组件重新挂载 setEditorKeys(prev => ({ ...prev, [editorId]: Date.now() })); }; return ( <div ref={setNodeRef} style={{ transform: CSS.Transform.toString(transform), transition }} {...attributes} {...listeners} onDragEnd={handleDragEnd} > <TinyMCEEditor key={editorKeys[editorId]} editorId={editorId} content={editorContents[editorId]} onContentChange={updateEditorContent} /> </div> ); };
- TinyMCE组件中正确销毁实例
在编辑器组件卸载时销毁TinyMCE实例,避免内存泄漏,同时确保重新挂载时初始化新实例:
const TinyMCEEditor = ({ editorId, content, onContentChange }) => { const editorRef = useRef(null); const handleEditorChange = (newContent) => { onContentChange(editorId, newContent); }; // 组件卸载时销毁编辑器实例 useEffect(() => { const instance = editorRef.current; return () => { if (instance) instance.destroy(); }; }, []); return ( <Editor ref={editorRef} initialValue={content} onEditorChange={handleEditorChange} // 你的TinyMCE配置... /> ); };
补充说明
- 这种方式通过重新挂载组件彻底重建了编辑器与DOM的关联,能解决绝大多数拖动后的失效问题。
- 如果你的TinyMCE配置中有自定义插件或事件监听,重新挂载时会自动重新初始化,无需额外处理。
- 若拖动时存在布局动画,无需额外等待动画结束,更新Key的操作会在动画完成后触发组件重建(React的状态更新是异步的)。
内容的提问来源于stack exchange,提问作者Jayss230
相关产品推荐
相关产品推荐

