React Quill编辑器输入异常:光标错位、退格失效求助
React Quill光标跳转、退格异常问题修复
问题原因
你的QuillEditor组件同时维护了内部状态editorHtml和接收父组件传入的value,导致编辑器出现状态冲突:每次输入时,子组件先更新自身state,再通知父组件更新editorContent,父组件又把新值传回子组件,触发编辑器重新渲染,光标位置因此丢失、出现跳转;退格异常也是因为重复渲染打断了编辑器的正常事件处理。
修复步骤
1. 移除QuillEditor内部的冗余状态
删除组件内的editorHtml状态,直接以父组件传入的value作为编辑器的唯一数据源,避免双向状态冲突。
2. 简化编辑器内容变更逻辑
直接在handleChange中调用父组件的onEditorChange,不需要先更新自身state。
修改后的QuillEditor.js代码
import React from 'react'; import ReactQuill, { Quill } from 'react-quill'; import "react-quill/dist/quill.snow.css"; import ImageResize from "quill-image-resize-module-react"; const __ISMSIE__ = navigator.userAgent.match(/Trident/i) ? true : false; var icons = Quill.import("ui/icons"); Quill.register("modules/imageResize", ImageResize); icons["undo"] = `<svg viewbox="0 0 18 18"> <polygon class="ql-fill ql-stroke" points="6 10 4 12 2 10 6 10"></polygon> <path class="ql-stroke" d="M8.09,13.91A4.6,4.6,0,0,0,9,14,5,5,0,1,0,4,9"></path> </svg>`; icons["redo"] = `<svg viewbox="0 0 18 18"> <polygon class="ql-fill ql-stroke" points="12 10 14 12 16 10 12 10"></polygon> <path class="ql-stroke" d="M9.91,13.91A4.6,4.6,0,0,1,9,14a5,5,0,1,1,5-5"></path> </svg>`; class QuillEditor extends React.Component { _isMounted; reactQuillRef = null; constructor(props) { super(props); } componentDidMount() { this._isMounted = true; } componentWillUnmount() { this._isMounted = false; } handleChange = (html) => { // 直接通知父组件更新,不再维护内部状态 this.props.onEditorChange(html); }; undoHandler = () => { this.reactQuillRef.editor.history.undo("undo"); }; redoHandler = () => { this.reactQuillRef.editor.history.redo("redo"); }; // 补充modules定义(原代码缺失,避免功能异常) modules = { imageResize: { parchment: Quill.import('parchment'), modules: ['Resize', 'DisplaySize'] }, toolbar: [ ['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], [{ 'list': 'ordered'}, { 'list': 'bullet' }], [{ 'color': [] }, { 'background': [] }], ['link', 'image'], ['undo', 'redo'] ] }; render() { return ( <div> <ReactQuill style={{height: '500px', padding: '0px', width: '100%', maxWidth: '1150px' }} ref={(el) => { this.reactQuillRef = el }} theme={'snow'} onChange={this.handleChange} modules={this.modules} value={this.props.value || (__ISMSIE__ ? "<p> </p>" : "")} placeholder={this.props.placeholder} /> </div> ) } } export default QuillEditor;
3. 优化父组件PostInfo.jsx的逻辑
确保onEditorChange直接更新状态,避免多余的中间处理:
// 简化onEditorChange const onEditorChange = (value) => { console.log("onEditorChange called"); setEditorContent(value); }; // 渲染QuillEditor时简化回调 <QuillEditor value={editorContent} onEditorChange={onEditorChange} />
额外注意事项
- 确保父组件的
editorContent初始化和更新不会触发不必要的重渲染,比如避免在useEffect中重复设置相同的值。 - 如果编辑器仍有异常,检查是否有其他组件逻辑导致PostInfo组件频繁重渲染,可以用
React.memo包裹QuillEditor组件,减少不必要的重渲染:
export default React.memo(QuillEditor);
内容的提问来源于stack exchange,提问作者sultan.h
相关产品推荐
相关产品推荐

