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
相关产品推荐
相关产品推荐

