React集成CKEditor5自定义解耦文档编辑器仅显示经典视图问题
React项目CKEditor5解耦编辑器始终渲染为经典视图问题修复
问题现象
- 目标:在React项目中接入搭载自定义插件的CKEditor5解耦文档编辑器
- 异常:页面始终渲染经典编辑器样式,即使替换引入官方
@ckeditor/ckeditor5-build-decoupled-document包的DecoupledEditor,问题仍存在 - 现有实现代码:
import { CKEditor } from "@ckeditor/ckeditor5-react"; import Editor from "ckeditor5-custom-build/build/ckeditor"; function App() { let editorr = null; return ( <div className="App"> <CKEditor onReady={(editor) => { console.log("Editor is ready to use!", editor); editor.ui .getEditableElement() .parentElement.insertBefore( editor.ui.view.toolbar.element, editor.ui.getEditableElement() ); editorr = editor; }} onError={(error, { willEditorRestart }) => { if (willEditorRestart) { editorr.ui.view.toolbar.element.remove(); } }} onChange={(event, editor) => console.log({ event, editor })} editor={Editor} data="<p>Hello from CKEditor 5's decoupled editor!</p>" /> </div> ); } export default App;
- 相关截图:
- 项目目录结构:

- 前端运行效果:

- 项目目录结构:
核心原因
这类问题90%以上是自定义构建包的基类选错:解耦编辑器(DecoupledEditor)和经典编辑器(ClassicEditor)是完全独立的编辑器实现,不能通过前端手动挂载工具栏的方式把经典编辑器改成解耦编辑器。如果自定义构建ckeditor5-custom-build时选择了ClassicEditor作为基类,不管React端怎么写逻辑,最终加载的都是经典编辑器。
解决步骤
- 修正自定义构建包的基类配置
打开自定义构建目录下的src/ckeditor.js文件,确认基类引入的是解耦编辑器而非经典编辑器:
// 自定义构建入口文件 // 必须引入DecoupledEditor作为基类,不要引入ClassicEditor import DecoupledEditorBase from '@ckeditor/ckeditor5-editor-decoupled/src/decouplededitor'; // 引入需要的所有插件 import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic'; // ...其他自定义插件 export default class DecoupledEditor extends DecoupledEditorBase {} // 插件和工具栏配置挂载到DecoupledEditor上 DecoupledEditor.builtinPlugins = [ Essentials, Paragraph, Bold, Italic // 其余插件 ]; DecoupledEditor.defaultConfig = { toolbar: { items: [ 'bold', 'italic' // 其余工具栏按钮 ] }, // 其余配置项 };
- 重新构建自定义包
修改完配置后,进入ckeditor5-custom-build目录,重新执行构建命令生成新的产物:
npm run build
- 清缓存验证
回到React项目,删除项目缓存(比如node_modules/.cache目录),重启开发服务,避免旧的经典编辑器产物被缓存加载。 - 验证逻辑正确性
如果想快速排除React端代码问题,可以先临时引入官方预构建的解耦包测试:
npm install @ckeditor/ckeditor5-build-decoupled-document
把组件里的Editor引入替换为:
import Editor from "@ckeditor/ckeditor5-build-decoupled-document";
如果这时候能正常渲染解耦编辑器,说明React端逻辑没问题,问题100%出在自定义构建的配置上。
5. 修正React端工具栏挂载逻辑
现有代码在编辑器重启时容易出现工具栏残留问题,可以优化为:
import { CKEditor } from "@ckeditor/ckeditor5-react"; import Editor from "ckeditor5-custom-build/build/ckeditor"; function App() { let editorInstance = null; return ( <div className="App"> <CKEditor onReady={(editor) => { // 单独创建工具栏容器,避免DOM操作冲突 const toolbarWrapper = document.createElement('div'); toolbarWrapper.className = 'ck decoupled-toolbar'; toolbarWrapper.appendChild(editor.ui.view.toolbar.element); // 把工具栏插入到编辑区上方 editor.ui.getEditableElement().parentElement.insertBefore( toolbarWrapper, editor.ui.getEditableElement() ); editorInstance = editor; }} onError={(error, { willEditorRestart }) => { // 编辑器重启前移除旧的工具栏DOM,避免重复渲染 if (willEditorRestart && editorInstance) { const oldToolbar = editorInstance.ui.view.toolbar.element; oldToolbar?.parentElement?.remove(); } console.error(error); }} onChange={(event, editor) => console.log({ event, editor })} editor={Editor} data="<p>Hello from CKEditor 5's decoupled editor!</p>" /> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者PRIYESH PANDEY
相关产品推荐
相关产品推荐

