Draft-JS编辑器从服务端加载内容后仅显示原生Emoji问题求助
Draft-JS 仅显示原生Emoji问题排查与解决办法
问题描述
我碰到了一个Draft-JS的奇怪问题:当我从服务端获取contentState数据,通过convertFromRaw转换后传入编辑器,里面的Emoji只能显示系统原生样式;但在把内容发送到服务端之前,聊天编辑器里的Emoji显示完全正常。
相关代码如下:
流程代码
const contentState = convertFromRaw(JSON.parse(comment.message)) const editorState = EditorState.createWithContent(contentState) <ChatTemplate user={currentUser === comment.userId} value={editorState} time={moment(comment.createdAt).startOf('second').fromNow()} />
编辑器组件代码
const ChatTemplate = (p)=>( <div className='globalMassage-cont' data-user={p.user} > <div className='globalMassage-value'> <Editor editorState={p.value} plugins={plugins} readOnly /> </div> </div> )
导入与常量定义
import Editor, { createEditorStateWithText } from "draft-js-plugins-editor"; import createEmojiPlugin from "draft-js-emoji-plugin"; import { EditorState, ContentState, convertFromRaw } from "draft-js"; const emojiPlugin = createEmojiPlugin(); const { EmojiSuggestions, EmojiSelect } = emojiPlugin; const plugins = [emojiPlugin];
原因分析
这个问题的核心在于draft-js-emoji-plugin的渲染逻辑没有参与到EditorState的初始化过程:
- 当你在编辑器里插入插件提供的Emoji时,插件会给对应的内容块添加专属的entity元数据,用来标记这是需要插件自定义渲染的Emoji。
- 但
convertFromRaw是Draft-JS核心的转换方法,它只会处理基础的ContentState结构,不会触发插件的解析逻辑。所以当你直接用它创建EditorState时,插件无法识别那些带专属标记的Emoji,只能 fallback 到系统原生Emoji显示。
解决办法
这里有两种靠谱的解决思路,你可以根据自己的场景选择:
方法一:初始化EditorState时传入插件的Decorator
draft-js-emoji-plugin提供了专属的decorator,用来处理Emoji的渲染逻辑。你只需要在创建EditorState时把它传进去,插件就能在初始化阶段识别并处理Emoji内容:
修改你的流程代码:
// 先解析服务端返回的原始数据 const rawContent = JSON.parse(comment.message); const contentState = convertFromRaw(rawContent); // 关键:传入emojiPlugin的decorator,让插件参与初始化 const editorState = EditorState.createWithContent( contentState, emojiPlugin.decorator ); <ChatTemplate user={currentUser === comment.userId} value={editorState} time={moment(comment.createdAt).startOf('second').fromNow()} />
方法二:确保服务端存储完整的插件处理数据
如果方法一没生效,你需要检查发送到服务端的数据是否完整。在发送内容前,必须用convertToRaw导出包含插件元数据的完整ContentState:
示例发送代码:
// 获取当前编辑器的完整ContentState const currentContent = editorState.getCurrentContent(); // 转换为原始JSON结构(包含插件添加的Emoji元数据) const rawContent = convertToRaw(currentContent); // 发送到服务端(注意转成JSON字符串) fetch('/api/save-comment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: JSON.stringify(rawContent) }) });
确保服务端存储的是这个完整的rawContent,而不是被截断或修改过的数据。这样当你从服务端取回数据转换时,插件就能正确识别Emoji标记。
验证步骤
修改后重新测试:
- 发送一条带插件Emoji的消息到服务端
- 刷新页面,从服务端取回这条消息
- 检查编辑器里的Emoji是否显示为插件样式,而非原生样式
内容的提问来源于stack exchange,提问作者elad BA
相关产品推荐
相关产品推荐

