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

如何从Lexical富编辑器的editorState获取HTML及选择存储格式

Lexical编辑器:HTML vs JSON存储选择及HTML生成/展示方案

存储格式对比与选择

JSON格式(Lexical原生状态)

  • 优势:完全保留编辑器的所有原生状态,包括自定义节点、选区细节、特殊样式,后续在Lexical里重新编辑时能100%还原,不会丢任何编辑器特有功能。体积也相对可控,适合需要二次编辑的场景。
  • 劣势:不能直接在编辑器外展示,得额外转成HTML才能渲染。

HTML格式

  • 优势:拿到就能直接在浏览器或其他支持HTML的地方展示,不用额外解析步骤,适合只看不改的内容。
  • 劣势:存的是渲染后的结构,丢了Lexical的原生状态信息,要是后续想在Lexical里重新编辑,把HTML转回去很可能会丢自定义节点或复杂格式,兼容性拉胯。

总结建议

  • 要是内容之后还要在Lexical里编辑,优先存JSON,需要展示时再转HTML。
  • 要是内容只看不改,直接存HTML就行。
  • 也可以两种都存,兼顾编辑和展示,就是多占点存储成本。

实现HTML生成及外部展示

Lexical官方提供了@lexical/html包来做状态和HTML的互转,先装包:

npm install @lexical/html

1. 生成JSON/HTML并存储

修改你的示例代码,加入生成逻辑(注意要拿到Lexical编辑器实例):

import { $generateHtmlFromNodes } from '@lexical/html';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';

const EditorWrapper = ({ changeHandler, placeholder, aditionalTools, editorConfig }) => {
  // 获取Lexical编辑器实例
  const [editor] = useLexicalComposerContext();

  const handleChange = (editorState) => {
    // 生成原生JSON状态
    const editorJson = editorState.toJSON();
    // 生成HTML内容
    const editorHtml = editorState.read(() => {
      return $generateHtmlFromNodes(editor, null);
    });

    // 把数据传给外部处理(比如存数据库)
    if (changeHandler) {
      changeHandler({ json: editorJson, html: editorHtml });
    }
  };

  return (
    <LexicalComposer initialConfig={editorConfig}>
      <div className="editor-container">
        <ToolbarPlugin aditionalTools={aditionalTools} />
        <div className="editor-inner">
          <RichTextPlugin
            contentEditable={<ContentEditable className="editor-input" />}
            placeholder={<Placeholder placeholder={placeholder} />}
          />
          <OnChangePlugin ignoreInitialChange onChange={handleChange} />
        </div>
      </div>
    </LexicalComposer>
  );
};

2. 编辑器外部展示HTML

直接渲染存储的HTML

如果存的是HTML,用React的dangerouslySetInnerHTML渲染(一定要做XSS过滤!):

// 先装XSS过滤库:npm install dompurify
import DOMPurify from 'dompurify';

const ContentDisplay = ({ htmlContent }) => {
  // 过滤恶意HTML
  const sanitizedHtml = DOMPurify.sanitize(htmlContent);
  
  return (
    <div 
      className="content-display"
      dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
    />
  );
};

从JSON转HTML再渲染

如果存的是JSON,先转成HTML再渲染:

import { $generateHtmlFromNodes } from '@lexical/html';
import { createEditor, EditorState } from 'lexical';
import DOMPurify from 'dompurify';

// JSON转HTML工具函数
const jsonToHtml = (editorJson) => {
  const editor = createEditor();
  let html = '';
  editor.update(() => {
    EditorState.fromJSON(editor, editorJson);
    html = $generateHtmlFromNodes(editor, null);
  });
  return DOMPurify.sanitize(html);
};

// 使用示例
const StoredContent = ({ storedJson }) => {
  const displayHtml = jsonToHtml(storedJson);
  return <ContentDisplay htmlContent={displayHtml} />;
};

注意点

  • 自定义节点:如果用了Lexical自定义节点,要在$generateHtmlFromNodes的第二个参数里传自定义节点的HTML转换器,不然转出来的HTML会丢自定义节点的内容。
  • XSS风险:不管是直接存HTML还是转出来的HTML,都必须做过滤,别让恶意脚本跑起来。

内容的提问来源于stack exchange,提问作者Rupinderpal Thind

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:27:37