使用Lexical的$generateHtmlFromNodes序列化HTML时遇状态错误求助
解决Lexical $generateHtmlFromNodes "无法找到活跃编辑器状态" 错误
错误核心原因
带$前缀的Lexical工具函数(比如$generateHtmlFromNodes)依赖活跃的编辑器上下文,必须在editorState.read()或editor.update()的同步回调中执行,直接在外部调用会脱离上下文,触发状态找不到的错误。另外,直接用JSON.stringify(editorState)无法正确序列化编辑器状态,需要使用官方提供的方法。
修复方案
- 将HTML生成逻辑包裹在上下文回调中
把$generateHtmlFromNodes的调用放到editorState.read()的回调内,确保运行在正确的编辑器上下文环境中。 - 正确序列化编辑器状态
使用editorState.toJSON()代替直接JSON.stringify(editorState),这是Lexical官方推荐的状态序列化方式。
修改后的父组件代码
export default function EmailClient() { const editorRef = useRef<LexicalEditor>(); const handleSendEmail = () => { const editor = editorRef.current; if (!editor) return; // 先判断编辑器是否完成初始化 const editorState = editor.getEditorState(); // 正确序列化编辑器状态 const jsonState = editorState.toJSON(); console.log('Serialized Editor State', jsonState); // 在read回调中执行HTML生成逻辑 let htmlString = ''; editorState.read(() => { htmlString = $generateHtmlFromNodes(editor, null); }); console.log('Generated HTML', htmlString); // 此处可继续处理邮件发送逻辑 }; return ( <> <Editor editorRef={editorRef} /> <Button text="send" function={handleSendEmail} /> </> ); }
可选优化:Editor组件的editorRef赋值逻辑
原代码中OnChangePlugin每次内容变更都重复赋值editor的操作没必要,可改为在编辑器初始化时一次性赋值:
export const Editor = (props: EditorProps) => { const initialConfig = { namespace: 'MyEditor', editable: true, nodes: [ImageNode], theme: myTheme, onError(error) { throw error; }, }; const editor = useLexicalComposerContext(); useEffect(() => { props.editorRef.current = editor; }, [editor, props.editorRef]); return ( <div className="relative rounded-sm border border-gray-200 bg-white shadow-sm"> <LexicalComposer initialConfig={initialConfig}> <Toolbar /> <ImagesPlugin /> <RichTextPlugin contentEditable={ <ContentEditable autoCorrect className="min-h-[450px] resize-none overflow-hidden text-ellipsis py-[15px] px-2.5 outline-none" /> } placeholder={null} /> <HistoryPlugin /> </LexicalComposer> </div> ); };
内容的提问来源于stack exchange,提问作者Rafael Zasas
相关产品推荐
相关产品推荐

