如何为Facebook Lexical富文本编辑器组件传入文本并初始化
实现基于Lexical的富文本编辑器组件替换Material UI TextField
1. 安装依赖
首先安装Lexical核心包和React绑定:
npm install lexical @lexical/react
2. 封装MyLexicalRichTextEditor组件
下面是完整的组件实现,支持接收value prop(纯文本或Lexical JSON格式),并通过onChange返回Lexical编辑器状态对象:
import { useEffect, useRef } from 'react'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { $getRoot, $getSelection, $createParagraphNode, $createTextNode, $isRangeSelection, parseEditorState, stringifyEditorState } from 'lexical'; // 辅助函数:将纯文本转换为Lexical编辑器状态 function textToEditorState(text) { return (editor) => { const root = $getRoot(); const selection = $getSelection(); // 清空现有内容 root.clear(); // 创建段落和文本节点 const paragraph = $createParagraphNode(); const textNode = $createTextNode(text); paragraph.append(textNode); root.append(paragraph); // 设置光标到末尾 if ($isRangeSelection(selection)) { selection.setStart(textNode, text.length); selection.setEnd(textNode, text.length); } }; } // 内部组件:处理编辑器状态同步和回调 function EditorSync({ value, onChange }) { const [editor] = useLexicalComposerContext(); const isInitialRender = useRef(true); // 同步外部value到编辑器 useEffect(() => { if (isInitialRender.current) { isInitialRender.current = false; return; } if (typeof value === 'string') { // 纯文本输入 editor.update(textToEditorState(value)); } else if (typeof value === 'object' && value !== null) { // Lexical JSON格式输入 editor.setEditorState(parseEditorState(JSON.stringify(value))); } }, [editor, value]); // 监听编辑器变化,触发onChange useEffect(() => { const unregister = editor.registerUpdateListener(({ editorState }) => { if (!isInitialRender.current) { const serializedState = JSON.parse(stringifyEditorState(editorState)); onChange(serializedState); } }); return unregister; }, [editor, onChange]); return null; } export default function MyLexicalRichTextEditor({ value = '', onChange }) { // 初始化编辑器配置 const initialConfig = { namespace: 'MyLexicalEditor', onError: (error) => console.error('Lexical Error:', error), editorState: (editor) => { if (typeof value === 'string') { textToEditorState(value)(editor); } else if (typeof value === 'object' && value !== null) { return parseEditorState(JSON.stringify(value)); } }, }; return ( <LexicalComposer initialConfig={initialConfig}> <EditorSync value={value} onChange={onChange} /> <RichTextPlugin contentEditable={<ContentEditable className="editor-content" />} placeholder={<p>输入内容...</p>} /> <HistoryPlugin /> </LexicalComposer> ); }
3. 在React应用中使用组件
import { useState } from 'react'; import MyLexicalRichTextEditor from './MyLexicalRichTextEditor'; function App() { // 初始值可以是纯文本 const [editorContent, setEditorContent] = useState('初始文本内容'); const handleChange = (lexicalState) => { // 这里可以将lexicalState保存到后端或本地状态 setEditorContent(lexicalState); // 如果需要获取纯文本,可从lexicalState中解析: // const plainText = lexicalState.root.children[0]?.children[0]?.text || ''; }; return ( <div> <h2>自定义Lexical编辑器</h2> <MyLexicalRichTextEditor value={editorContent} onChange={handleChange} /> </div> ); } export default App;
关键细节说明
- value prop兼容:组件同时支持纯文本和Lexical序列化的JSON对象作为输入,自动处理转换逻辑。
- 状态同步:通过
useEffect监听外部value变化,确保编辑器内容与外部状态一致;同时注册编辑器更新监听,将内部状态变化同步到外部。 - 内容渲染:默认将输入文本渲染为普通段落,符合需求;如果需要扩展富文本功能,可添加更多Lexical插件(如粗体、斜体工具条)。
内容的提问来源于stack exchange,提问作者Divyanth Jayaraj
相关产品推荐
相关产品推荐

