将MUIRichTextEditor用作Redux Form字段时光标跳至开头的问题
解决MUIRichTextEditor结合Redux Form时的重渲染与光标位置问题
核心问题分析
你当前的实现每次按键都会触发Redux Store更新,导致组件重渲染;而通过defaultValue传入RawDraftContentState的方式会重置编辑器状态,无法保留光标位置。要解决这个问题,需要将编辑器改为受控模式,由组件自身维护EditorState,仅在外部值(Redux Store中的值)变化时才同步更新编辑器状态。
修改后的实现代码
import { EditorState, ContentState, convertFromHTML } from 'draft-js'; import { stateToHTML } from 'draft-js-export-html'; import { MuiThemeProvider } from '@material-ui/core/styles'; import MUIRichTextEditor from 'mui-rte'; class MYRichText extends Component { lastRichTextHTMLValue = null; constructor(props) { super(props); // 初始化编辑器状态 const htmlValue = props.input.value || "<p><br></p>"; const convertedValue = convertFromHTML(htmlValue); const contentState = ContentState.createFromBlockArray( convertedValue.contentBlocks, convertedValue.entityMap ); this.state = { editorState: EditorState.createWithContent(contentState) }; } componentDidUpdate(prevProps) { // 仅当Redux中的值发生变化时,更新编辑器状态 if (prevProps.input.value !== this.props.input.value) { const htmlValue = this.props.input.value || "<p><br></p>"; const convertedValue = convertFromHTML(htmlValue); const contentState = ContentState.createFromBlockArray( convertedValue.contentBlocks, convertedValue.entityMap ); this.setState({ editorState: EditorState.createWithContent(contentState) }); } } onRichTextChange = (editorState) => { const currentContent = editorState.getCurrentContent(); const richTextAsHTML = stateToHTML(currentContent); // 避免无意义的Redux更新,仅在内容真正变化时同步 if (richTextAsHTML !== this.lastRichTextHTMLValue) { this.lastRichTextHTMLValue = richTextAsHTML; this.props.input.onChange(richTextAsHTML); } // 更新组件内部的编辑器状态,保留光标位置 this.setState({ editorState }); }; render() { return ( <MuiThemeProvider theme={richEditorTheme}> <MUIRichTextEditor controls={["title", "bold", "italic", "underline", "strikethrough"]} label="Description" editorState={this.state.editorState} onChange={this.onRichTextChange} /> </MuiThemeProvider> ); } }
关键改动说明
- 组件内部维护
EditorState:将编辑器状态存入组件自身的state,不再依赖defaultValue每次重渲染重置状态,光标位置会被自动保留。 - 监听外部值变化:通过
componentDidUpdate对比前后props.input.value,仅当Redux中的值真正改变时,才重新生成EditorState并更新编辑器。 - 受控模式绑定:给
MUIRichTextEditor传入editorState属性替代defaultValue,并在onChange中同步更新内部状态与Redux Store。 - 优化Redux更新逻辑:仅当内容的HTML格式真正变化时,才调用
input.onChange同步到Redux,避免不必要的Store更新与组件重渲染。
内容的提问来源于stack exchange,提问作者Yoram Gronich
相关产品推荐
相关产品推荐

