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

react-wysiwyg点击textarea空白页 getBlockMap报错

问题根因

报错Uncaught TypeError: contentState.getBlockMap is not a function的核心原因是传入Draft API的参数不是合法的ContentState实例,是普通JS对象/格式错误的数据,代码里一共有4个明确问题:

  • convertFromHTML返回值直接传给EditorState.createWithContent的写法错误:原生Draft.js的convertFromHTML返回结构是{contentBlocks, entityMap},不能直接作为ContentState使用;只有draft-convert库的同名方法才会直接返回ContentState实例。
  • 数据格式混用:你在respChange里把convertToRaw(state.getCurrentContent())(普通JSON对象,不是ContentState)存到了上层状态,下次组件渲染时直接把这个raw格式对象传给convertFromHTML,转换出来的结果完全不符合ContentState结构,编辑器触发更新时就会抛出找不到getBlockMap方法的错误。
  • 组件参数解构有语法错误:const TabContent = ({ onChange, resp, , status }) 里resp后面多了一个多余逗号,会导致props解构异常,拿到的resp值不符合预期。
  • DOM属性名书写错误:wrapperclassName、editorclassName没有按React驼峰规范书写,正确属性名是wrapperClassName、editorClassName,写错会导致样式不生效。
修复方案

按以下规则调整代码即可:

  1. 统一数据格式:上层状态、组件间传递的resp/name字段统一存RawDraftContent格式(就是convertToRaw返回的JSON结构),只有在提交接口、渲染纯HTML的时候再做格式转换,避免字符串、Raw对象、ContentState实例混传。
  2. 初始化编辑器时先判断传入值的类型,对应做格式转换,不合法值直接返回空编辑器状态。
  3. 修正语法错误,补全未闭合的标签、缺失的属性绑定。

修复后的核心代码

// 按你用的工具库正确导入方法,以下是常用搭配示例
import { EditorState, convertFromRaw, convertToRaw } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import { convertToHTML, convertFromHTML } from 'draft-convert';
import { useState } from 'react';

const TabContent = ({ onChange, resp, name, status }) => {
  // 统一封装编辑器初始化逻辑
  const initEditorState = (content) => {
    if (!content) return EditorState.createEmpty();
    // 处理RawDraft格式的存值
    if (typeof content === 'object' && content.blocks) {
      return EditorState.createWithContent(convertFromRaw(content));
    }
    // 处理HTML字符串格式的初始值
    if (typeof content === 'string') {
      return EditorState.createWithContent(convertFromHTML(content));
    }
    return EditorState.createEmpty();
  };

  // resp编辑器状态
  const [respEditor, setRespEditor] = useState(() => initEditorState(resp));
  // name编辑器逻辑和resp完全一致,照着实现即可
  const [nameEditor, setNameEditor] = useState(() => initEditorState(name));

  function respChange(state) {
    setRespEditor(state);
    onChange({
      resp: convertToRaw(state.getCurrentContent()),
      name,
      status
    });
  }

  // name编辑器change事件照着respChange写即可
  function nameChange(state) {
    setNameEditor(state);
    onChange({
      resp: convertToRaw(respEditor.getCurrentContent()),
      name: convertToRaw(state.getCurrentContent()),
      status
    });
  }

  const handle = async (e) => {
    e.preventDefault();
    try {
      await fetch("", {
        method: "POST",
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          // 提交时再转成HTML字符串
          resp: convertToHTML(respEditor.getCurrentContent()),
          name: convertToHTML(nameEditor.getCurrentContent()),
          status
        })
      });
    } catch (err) {
      console.log(err);
    }
  };

  return (
    <form onSubmit={handle}>        
      <Editor
        editorState={respEditor}
        onEditorStateChange={respChange}
        wrapperClassName="wrapperclassName"
        editorClassName="editorclassName"
        toolbar={{
          options: ["inline"],
          inline: { inDropdown: false }
        }}
      />
      {/* name编辑器照着resp编辑器放即可 */}
      <Editor
        editorState={nameEditor}
        onEditorStateChange={nameChange}
        wrapperClassName="wrapperclassName"
        editorClassName="editorclassName"
      />
      <input
        type="radio"
        value="B"
        checked={status === "B"}
        onChange={(e) =>
          onChange({
            resp: convertToRaw(respEditor.getCurrentContent()),
            name: convertToRaw(nameEditor.getCurrentContent()),
            status: e.target.value
          })
        }
      />
      <button type="submit">提交</button>
    </form>
  );
};

如果你没有用draft-convert库,用的是Draft.js原生自带的convertFromHTML,初始化HTML内容的逻辑要替换成下面的写法:

import { ContentState } from 'draft-js';
const { contentBlocks, entityMap } = convertFromHTML(content);
const contentState = ContentState.createFromBlockArray(contentBlocks, entityMap);
return EditorState.createWithContent(contentState);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 20:42:21