You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:03:34