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

DraftJS:如何将编辑器内容存入Redux store?Reducer状态异常排查

问题分析与解决方案

这个问题我之前也碰到过,核心原因是Draft.js的EditorState是Immutable.js的Record实例,而你的Redux状态里存储的不是这个合法实例,而是被转成了普通对象,自然就没有getCurrentInlineStyle这类内置方法,触发报错。而构造函数里直接创建时,你得到的是标准的Record实例,所以一切正常。

下面来拆解可能的错误点和对应的解决办法:

1. 检查Reducer中EditorState的创建/更新方式

最常见的坑是在Reducer里错误地把Record实例转成了普通对象:

  • 错误写法:用对象扩展运算符解构EditorState(会把Immutable Record转成普通JS对象)
// ❌ 错误:把EditorState转成了普通对象
case 'UPDATE_EDITOR':
  return {
    ...state,
    editorState: { ...state.editorState } 
  };
  • 正确写法:直接使用Draft.js提供的方法创建/修改EditorState,保持它的Record类型:
import { EditorState } from 'draft-js';

const initialState = {
  editorState: EditorState.createEmpty() // 初始化时直接生成Record实例
};

function editorReducer(state = initialState, action) {
  switch(action.type) {
    case 'RESET_EDITOR':
      return {
        ...state,
        editorState: EditorState.createEmpty() // 重置时重新生成合法实例
      };
    case 'UPDATE_EDITOR':
      // action.payload必须是一个合法的EditorState实例
      return {
        ...state,
        editorState: action.payload 
      };
    // 如果需要修改EditorState的内部属性,要用它的Immutable方法
    case 'CHANGE_EDITOR_CONTENT':
      return {
        ...state,
        editorState: state.editorState.set('currentContent', action.payload.content)
      };
    default:
      return state;
  }
}

2. 检查是否使用了状态持久化中间件(如redux-persist)

如果你的项目用了redux-persist这类持久化工具,它默认会把Immutable对象序列化成普通JSON,恢复时就变成了普通对象,不再是Record实例。解决办法是给redux-persist添加Immutable转换器:

import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import immutableTransform from 'redux-persist-transform-immutable';

const persistConfig = {
  key: 'root',
  storage,
  transforms: [immutableTransform()] // 加入这个转换器,保持Immutable类型
};

const rootReducer = combineReducers({
  editor: editorReducer
});

export default persistReducer(persistConfig, rootReducer);

3. 备选方案:存储EditorState的原始JSON

如果你不想在Redux里直接存Immutable对象,可以把EditorState序列化成原始JSON存储,在组件中再转成实例:

  • Reducer中存储JSON:
const initialState = {
  editorStateRaw: EditorState.createEmpty().toJS()
};

function editorReducer(state = initialState, action) {
  switch(action.type) {
    case 'RESET_EDITOR':
      return {
        ...state,
        editorStateRaw: EditorState.createEmpty().toJS()
      };
    case 'UPDATE_EDITOR':
      return {
        ...state,
        editorStateRaw: action.payload.editorState.toJS()
      };
    default:
      return state;
  }
}
  • 组件中转换为EditorState实例:
import { EditorState, convertFromRaw } from 'draft-js';

class MyEditor extends React.Component {
  constructor(props) {
    super(props);
    // 从raw JSON还原EditorState
    this.state = {
      editorState: EditorState.createWithContent(convertFromRaw(props.editorStateRaw.content))
    };
  }

  // 监听props变化,实时更新
  componentDidUpdate(prevProps) {
    if (prevProps.editorStateRaw !== this.props.editorStateRaw) {
      this.setState({
        editorState: EditorState.createWithContent(convertFromRaw(this.props.editorStateRaw.content))
      });
    }
  }

  // ...其他编辑器逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:15:34