使用EditorJS无法编辑已保存数据:打开文件后编辑器为空
问题分析与解决方案
核心问题是异步时序不匹配:点击文件时,handleFileClick先获取内容并尝试调用selectedEditor.render,但此时EditorJS实例还在异步初始化过程中(useEffect在selectedFile更新后才开始加载并初始化编辑器),导致render方法根本没执行,编辑器自然显示为空。
修复方案1:初始化时直接传入内容(推荐)
调整useEffect逻辑,在创建EditorJS实例时直接传入选中文件的内容,无需手动调用render:
useEffect(() => { // 切换文件时先销毁旧编辑器实例,避免DOM冲突 if (selectedEditor) { selectedEditor.destroy(); setSelectedEditor(null); } if (selectedFile) { import('@editorjs/editorjs') .then((module) => { const EditorJs = module.default; const newEditorInstance = new EditorJs({ holder: 'editor-container', // 直接把选中文件的内容作为初始数据传入 data: selectedFile.content || { blocks: [] } }); newEditorInstance.isReady .then(() => { setSelectedEditor(newEditorInstance); }) .catch((error) => { console.error('初始化EditorJs出错:', error); }); }) .catch((error) => { console.error('加载EditorJS出错:', error); }); } }, [selectedFile]);
然后修改handleFileClick,只需要获取内容并更新selectedFile即可:
const handleFileClick = (folder, file) => { fetch(`http://localhost:3001/api/getFileContent/${folder.name}/${file.name}`) .then((response) => { if (!response.ok) { throw new Error(`请求失败,状态码: ${response.status}`); } return response.json(); }) .then((content) => { console.log('获取到的内容:', content); // 只更新选中文件状态,剩下的交给useEffect处理 setSelectedFile({ folder: folder.name, name: file.name, content }); }) .catch((error) => { console.error('获取文件内容出错:', error.message); }); };
修复方案2:监听编辑器实例就绪后渲染内容
如果不想修改初始化配置,可以新增一个useEffect,专门监听编辑器实例和文件内容的变化,确保两者都就绪后再调用render:
// 原初始化逻辑保持不变 useEffect(() => { if (selectedFile) { import('@editorjs/editorjs') .then((module) => { const EditorJs = module.default; const newEditorInstance = new EditorJs({ holder: 'editor-container', }); newEditorInstance.isReady .then(() => { setSelectedEditor(newEditorInstance); }) .catch((error) => { console.error('初始化EditorJs出错:', error); }); }) .catch((error) => { console.error('加载EditorJS出错:', error); }); } }, [selectedFile]); // 新增监听:编辑器就绪且有内容时渲染 useEffect(() => { if (selectedEditor && selectedFile?.content?.blocks) { selectedEditor.render({ blocks: selectedFile.content.blocks }) .catch(err => console.error('渲染内容出错:', err)); } }, [selectedEditor, selectedFile?.content]); // handleFileClick逻辑不变
额外注意事项
- 确保保存的
content严格符合EditorJS格式:必须包含blocks数组,每个块的type和data字段完整且正确。 - 切换文件时务必销毁旧编辑器实例,避免同一DOM容器绑定多个实例导致的异常。
内容的提问来源于stack exchange,提问作者ferrelwill
相关产品推荐
相关产品推荐

