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

从Firebase加载数据后无法编辑Draft.js编辑器文本

问题分析与修复方案

核心问题:编辑器状态被频繁重置

你的Editor组件每次渲染时都会通过EditorState.createWithContent(ContentState.createFromText(text))创建全新的编辑器状态,这会导致用户输入时,组件重渲染就会覆盖当前编辑状态,直接表现为光标固定、无法编辑。

修复步骤

1. 正确初始化和绑定编辑器状态

把编辑器状态的初始化与更新逻辑从组件props中剥离,放到useEffect中处理:

// 原编辑器状态初始化保留
const [editorState, setEditorState] = useState(() => EditorState.createEmpty());

// 当从数据库获取到文本内容时,更新编辑器状态
useEffect(() => {
  if (text) {
    const contentState = ContentState.createFromText(text);
    setEditorState(EditorState.createWithContent(contentState));
  }
}, [text]);

然后修改Editor组件的props,直接绑定已有的状态:

<Editor
  editorState={editorState}
  onEditorStateChange={setEditorState}
  wrapperClassName="wrapper-class"
  editorClassName="editor-class"
  toolbarClassName="toolbar-class"
/>

2. 修复文章获取的无限循环问题

获取文章的useEffect依赖中包含post,会导致每次post更新时重复触发请求,形成无限循环,移除该依赖:

useEffect(() => {
  const getPost = async () => {
    const docRef = doc(db, 'posts', id);
    try {
      const docSnap = await getDoc(docRef);
      const postData = docSnap.data();
      setPost(postData);
      const text = htmlToText(postData.body, {});
      setText(text);
    } catch (error) {
      console.log(error)
    }
  };
  getPost();
}, [id]); // 仅保留id作为依赖

3. 同步编辑器内容到表单数据

原转换HTML的useEffect依赖为空数组,无法随编辑器状态更新同步表单数据,修改依赖并优化更新逻辑:

useEffect(() => {
  const html = convertToHTML(editorState.getCurrentContent());
  setConvertedContent(html);
  setFormData(prev => ({ ...prev, body: html }));
}, [editorState]); // 依赖改为editorState,随编辑器状态更新触发

4. 优化图片URL同步逻辑

移除不必要的依赖,避免无效触发:

useEffect(() => {
  if (imageURL) {
    setFormData(prev => ({ ...prev, image: imageURL }));
  }
}, [imageURL]); // 仅保留imageURL作为依赖

额外建议:保留原文章格式

目前你把HTML转成纯文本再导入编辑器,会丢失原有的格式。可以使用draft-js-import-html库直接将HTML转换为Draft.js的ContentState,保留原文章格式:

  1. 安装依赖:npm install draft-js-import-html
  2. 修改文章获取逻辑:
import { stateFromHTML } from 'draft-js-import-html';

// 在getPost函数中替换htmlToText部分
const contentState = stateFromHTML(postData.body);
setEditorState(EditorState.createWithContent(contentState));
// 可删除text相关的useState及处理逻辑

内容的提问来源于stack exchange,提问作者Julian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:25:25