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

Vite React项目支持数学字符编辑器选型及Draft.js报错求助

支持数学字符的React文本编辑器问题:Draft.js粘贴报错及选型建议

我正在Vite React项目中开发一款支持除号、分数、幂等数学字符的文本编辑器,但试用的工具效果都不理想。当前使用Draft.js(配合react-draft-wysiwyg)时,粘贴数学题会触发以下错误:

DraftEditorLeaf.react.js:131 
 Uncaught TypeError: Cannot read properties of undefined (reading 'reduce')
    at DraftEditorLeaf2.render (DraftEditorLeaf.react.js:131:29)
    at finishClassComponent (react-dom.development.js:19781:31)
    at updateClassComponent (react-dom.development.js:19727:24)
    at beginWork (react-dom.development.js:21650:16)
    at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27490:7)
    at performUnitOfWork (react-dom.development.js:26596:12)
    at workLoopSync 

查看官方文档示例也出现了相同错误,我的实现代码如下:

import { convertFromRaw, convertToRaw, EditorState } from "draft-js";
import { useEffect, useState } from "react";
import { Editor as Editors } from "react-draft-wysiwyg";
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";

interface Prop {
  setText: any;
  placeholder: string;
}

// // Utility function to sanitize text
// const sanitizeText = (text: string): string => {
//   // Remove problematic characters or sanitize them
//   return text.replace(/[^\x20-\x7E]/g, ""); // Removes non-ASCII characters
// };

export default function Editor2({ setText, placeholder }: Prop) {
  const [editorState, setEditorState] = useState(() => {
    const initialContent = { blocks: [], entityMap: {} }; // Basic empty content
    return EditorState.createWithContent(convertFromRaw(initialContent));
  });

  const onEditorStateChange = (editorState: any) => {
    setEditorState(editorState);
    const plainText = editorState.getCurrentContent().getPlainText("\u0001");
    // const sanitizedText = sanitizeText(plainText); // Sanitize the text
    console.log("Editor State:", plainText);
    setText(plainText);
  };

  useEffect(() => {
    // console.log("Editor State:", editorState);
  }, [editorState]);

  return (
    <>
      <Editors
        editorStyle={{}}
        toolbarStyle={{
          background: "transparent",
          color: "white",
          border: "1px solid gray",
        }}
        wrapperStyle={{
          border: "1px solid gray",
          padding: 2,
        }}
        editorState={editorState}
        toolbarClassName="toolbarClassName"
        wrapperClassName="wrapperClassName"
        editorClassName="editorClassName"
        onEditorStateChange={onEditorStateChange}
        placeholder={placeholder}
        mention={{
          separator: " ",
          trigger: "@",
          suggestions: [
            { text: "APPLE", value: "apple" },
            { text: "BANANA", value: "banana", url: "banana" },
            { text: "CHERRY", value: "cherry", url: "cherry" },
            { text: "DURIAN", value: "durian", url: "durian" },
            { text: "EGGFRUIT", value: "eggfruit", url: "eggfruit" },
            { text: "FIG", value: "fig", url: "fig" },
            { text: "GRAPEFRUIT", value: "grapefruit", url: "grapefruit" },
            { text: "HONEYDEW", value: "honeydew", url: "honeydew" },
          ],
        }}
      />
    </>
  );
}

针对Draft.js报错的临时修复方案

  • 拦截粘贴事件处理特殊字符:绑定onPaste事件手动处理粘贴内容,将数学字符转换为Draft.js兼容格式,避免直接触发解析错误。示例:
import { Modifier } from "draft-js";

const handlePaste = (e: React.ClipboardEvent) => {
  e.preventDefault();
  const pastedText = e.clipboardData.getData('text');
  // 处理特殊数学字符,可根据需求扩展规则
  const processedText = pastedText.replace(/÷/g, '/').replace(/⅓/g, '1/3');
  // 插入处理后的内容到编辑器
  const contentState = editorState.getCurrentContent();
  const newContentState = Modifier.insertText(
    contentState,
    editorState.getSelection(),
    processedText
  );
  setEditorState(EditorState.push(editorState, newContentState, 'insert-characters'));
};

在Editors组件上添加onPaste={handlePaste}即可生效。

  • 回退到稳定版本:新版本的Draft.js或react-draft-wysiwyg可能存在兼容性问题,尝试降级到draft-js@0.11.7和react-draft-wysiwyg@1.15.0等稳定版本。

  • 修正初始内容结构:确保初始RawContent符合Draft.js规范,添加默认空块避免空状态解析异常:

const initialContent = {
  blocks: [
    {
      key: 'default-empty',
      text: '',
      type: 'unstyled',
      depth: 0,
      inlineStyleRanges: [],
      entityRanges: []
    }
  ],
  entityMap: {}
};

更适合数学场景的编辑器选型建议

  • Slate.js:高度可定制,支持自定义节点类型,可直接实现分数、幂等数学元素的渲染与编辑,适合构建复杂富文本编辑器。
  • Quill.js:支持自定义格式与模块,结合MathQuill插件可实现数学公式编辑,对特殊字符兼容性较好。
  • Tiptap:基于ProseMirror封装的开箱即用组件,支持tiptap-math等扩展插件,上手难度低于原生ProseMirror。
  • ProseMirror:专注富文本编辑的底层框架,能精确控制内容结构,完美适配数学符号与复杂排版需求。

内容的提问来源于stack exchange,提问作者Omokefe Ovie David

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:14:52