React项目中如何用Debounce获取Lexical编辑器的JSON状态与文本内容
实现Lexical编辑器状态防抖同步到服务器(React 18 + Lexical 0.3.8)
1. 确认依赖安装
先确保安装指定版本的依赖:
npm install react@^18.2.0 lexical@^0.3.8 @lexical/react@^0.3.8 # 或使用yarn yarn add react@^18.2.0 lexical@^0.3.8 @lexical/react@^0.3.8
2. 实现防抖函数
可以自定义轻量防抖函数,也可使用lodash.debounce,以下是自定义实现:
function debounce(func, delay) { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }
3. 构建带防抖同步的编辑器组件
核心是通过OnChangePlugin监听编辑器变化,提取JSON状态与纯文本后,通过防抖函数批量发送至服务器:
import React, { useCallback } 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 { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'; import { createEditor } from 'lexical'; import { $getRoot } from 'lexical'; // 防抖函数 function debounce(func, delay) { let timeoutId; return (...args) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; } // 发送数据到服务器的API const sendEditorData = async (stateJson, plainText) => { try { await fetch('/api/save-editor-data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ state: stateJson, text: plainText }), }); } catch (err) { console.error('保存编辑器数据失败:', err); } }; // 防抖后的发送函数,设置500ms延迟可按需调整 const debouncedSend = debounce(sendEditorData, 500); const DebouncedLexicalEditor = () => { const initialConfig = { namespace: 'MySyncEditor', theme: {}, // 可自定义编辑器主题样式 onError: (err) => console.error(err), }; // 处理编辑器变化的回调 const handleChange = useCallback((editorState) => { // 获取JSON格式的完整编辑器状态 const stateJson = editorState.toJSON(); // 获取纯文本内容(必须在read回调内执行Lexical DOM操作) let plainText = ''; editorState.read(() => { const root = $getRoot(); plainText = root.getTextContent(); }); // 触发防抖发送 debouncedSend(stateJson, plainText); }, []); return ( <LexicalComposer initialConfig={initialConfig}> <RichTextPlugin contentEditable={<ContentEditable />} placeholder={<div>开始输入内容...</div>} /> <HistoryPlugin /> {/* 监听编辑器变化 */} <OnChangePlugin onChange={handleChange} /> </LexicalComposer> ); }; export default DebouncedLexicalEditor;
关键细节说明
- JSON状态获取:通过
editorState.toJSON()直接拿到包含所有节点、格式的完整编辑器状态,可用于后续恢复编辑器内容。 - 纯文本提取:借助
editorState.read()回调与$getRoot().getTextContent()获取纯文本,这是Lexical官方推荐的读取DOM状态的方式,避免状态不一致问题。 - 防抖控制:将请求逻辑包裹在防抖函数中,减少频繁输入时的服务器请求次数,500ms延迟可根据业务需求调整。
- 版本适配:代码基于
lexical@0.3.8与@lexical/react@0.3.8编写,确保OnChangePlugin等API调用符合版本要求。
若需手动触发状态获取,可通过useLexicalComposerContext直接获取编辑器实例:
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; // 在组件内部 const [editor] = useLexicalComposerContext(); const getCurrentEditorState = () => { const currentState = editor.getEditorState(); // 后续处理逻辑同上述回调 };
内容的提问来源于stack exchange,提问作者Bhanu Sharma
相关产品推荐
相关产品推荐

