You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lexical.js中实现两个编辑器实例镜像同步的示例求助

Lexical.js 多编辑器实例同步更新实现示例

单向/双向同步核心实现

要实现两个Lexical编辑器实例的更新同步,核心思路是监听其中一个编辑器的editorState变化,然后将状态同步到另一个实例。需要添加同步标记避免循环触发更新。

纯JavaScript环境示例

import { createEditor } from 'lexical';
import { TextNode, ParagraphNode } from '@lexical/text';

// 初始化两个编辑器实例
const editor1 = createEditor({
  nodes: [TextNode, ParagraphNode],
});
const editor2 = createEditor({
  nodes: [TextNode, ParagraphNode],
});

// 标记是否正在同步,防止循环触发更新
let isSyncing = false;

// 监听editor1的状态变化,同步到editor2(单向同步)
editor1.registerUpdateListener(({ editorState }) => {
  if (isSyncing) return;
  isSyncing = true;
  editor2.setEditorState(editorState);
  isSyncing = false;
});

// 如果需要双向同步,添加editor2到editor1的监听
editor2.registerUpdateListener(({ editorState }) => {
  if (isSyncing) return;
  isSyncing = true;
  editor1.setEditorState(editorState);
  isSyncing = false;
});

React环境(@lexical/react)示例

import { useRef, useEffect } from 'react';
import { LexicalComposer, useLexicalComposerContext } from '@lexical/react';
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
import { TextNode, ParagraphNode } from '@lexical/text';

// 同步逻辑组件
const EditorSync = ({ targetEditor }) => {
  const [currentEditor] = useLexicalComposerContext();
  let isSyncing = false;

  useEffect(() => {
    if (!targetEditor) return;
    
    const unregisterListener = currentEditor.registerUpdateListener(({ editorState }) => {
      if (isSyncing) return;
      isSyncing = true;
      targetEditor.setEditorState(editorState);
      isSyncing = false;
    });

    return unregisterListener;
  }, [currentEditor, targetEditor]);

  return null;
};

// 主组件
export default function DualEditorSync() {
  const editorRef1 = useRef(null);
  const editorRef2 = useRef(null);

  return (
    <div style={{ display: 'flex', gap: '2rem', padding: '1rem' }}>
      <LexicalComposer initialConfig={{ nodes: [TextNode, ParagraphNode] }}>
        {({ editor }) => {
          editorRef1.current = editor;
          return (
            <>
              <EditorSync targetEditor={editorRef2.current} />
              <div style={{ width: '50%' }}>
                <h3>编辑器1</h3>
                <RichTextPlugin
                  contentEditable={<ContentEditable />}
                  placeholder={<div>输入内容同步到编辑器2</div>}
                />
                <HistoryPlugin />
              </div>
            </>
          );
        }}
      </LexicalComposer>

      <LexicalComposer initialConfig={{ nodes: [TextNode, ParagraphNode] }}>
        {({ editor }) => {
          editorRef2.current = editor;
          return (
            <>
              <EditorSync targetEditor={editorRef1.current} />
              <div style={{ width: '50%' }}>
                <h3>编辑器2</h3>
                <RichTextPlugin
                  contentEditable={<ContentEditable />}
                  placeholder={<div>输入内容同步到编辑器1</div>}
                />
                <HistoryPlugin />
              </div>
            </>
          );
        }}
      </LexicalComposer>
    </div>
  );
}

关于Lexical.js文档完善度的说明

Lexical官方文档确实存在内容覆盖不全的问题,尤其是高级自定义节点、复杂状态同步、边缘场景处理等方面的说明较为缺失。目前可以通过以下方式补充信息:

  • 查看官方仓库的examples目录,里面包含了很多实战场景的实现代码
  • 关注官方GitHub Issues,很多用户会分享遇到的问题及解决方案
  • 参与社区讨论,获取其他开发者的经验分享

内容的提问来源于stack exchange,提问作者jerome courtois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:18:28