多React应用嵌入Lexical编辑器同页面运行时出现活跃编辑器状态找不到错误
多React应用同页使用Lexical编辑器的焦点状态异常问题解决
问题描述
多个独立React应用嵌入同一页面,每个应用都包含Lexical编辑器时出现异常:
- 第一个获得焦点的编辑器可正常工作
- 切换到其他应用的编辑器时,抛出
Unable to find an active editor state错误 - 单个React应用内多编辑器无异常,仅跨独立应用时出现状态不同步,设置唯一命名空间无效
错误栈
Uncaught Error: Unable to find an active editor state. State helpers or node methods can only be used synchronously during the callback of editor.update() or editorState.read(). at getActiveEditorState (Lexical.dev.js:7379:1) at $getNodeByKey (Lexical.dev.js:721:1) at ParagraphNode.getLatest (Lexical.dev.js:4090:1) at ParagraphNode.getParent (Lexical.dev.js:3690:1) at ParagraphNode.getIndexWithinParent (Lexical.dev.js:3664:1) at internalResolveSelectionPoint (Lexical.dev.js:6682:1) at internalResolveSelectionPoints (Lexical.dev.js:6787:1) at internalCreateRangeSelection (Lexical.dev.js:6898:1) at internalCreateSelection (Lexical.dev.js:6851:1) at beginUpdate (Lexical.dev.js:8008:1)
解决方向
1. 隔离Lexical全局上下文
Lexical默认依赖全局EditorState上下文,多应用同页会互相干扰。需为每个独立React应用的Lexical实例配置独立上下文提供者:
import { LexicalComposer, LexicalComposerContext } from '@lexical/react'; import { createEditor } from 'lexical'; function AppEditor() { const config = { /* 编辑器基础配置 */ }; // 为当前应用创建独立编辑器实例 const [editor] = useState(() => createEditor(config)); return ( <LexicalComposerContext.Provider value={editor}> <LexicalComposer initialConfig={config}> {/* 你的编辑器UI组件 */} </LexicalComposer> </LexicalComposerContext.Provider> ); }
2. 手动绑定聚焦时的状态同步
在编辑器聚焦时,强制关联当前实例的状态,避免Lexical误获取其他应用的状态:
function EditorComponent() { const editor = useLexicalComposerContext(); useEffect(() => { const handleFocus = () => { // 聚焦时强制同步当前编辑器状态上下文 editor.update(() => {}, { tag: 'FOCUS_STATE_SYNC' }); }; editor.registerListener('focus', handleFocus); return () => editor.removeListener('focus', handleFocus); }, [editor]); return ( {/* 编辑器渲染内容 */} ); }
3. 隔离Webpack模块实例
如果多应用通过Webpack打包,确保Lexical相关模块不被共享:
- 在Webpack配置中,将
lexical、@lexical/react等包设置为非共享模块,避免全局单例冲突 - 禁止将Lexical加入模块联邦的
shared配置
4. 规范状态操作方式
所有Lexical状态操作必须绑定当前编辑器实例,禁止直接调用全局状态方法:
- 错误示例:直接调用全局
$getNodeByKey$getNodeByKey(nodeKey); - 正确示例:在
editor.update回调内执行操作editor.update(() => { const targetNode = $getNodeByKey(nodeKey); // 执行节点操作 });
内容的提问来源于stack exchange,提问作者Erik Nilsson
相关产品推荐
相关产品推荐

