TinyMCE在React中内容变化时无法触发onChange更新状态?
我在React项目里用TinyMCE编辑器,想把编辑内容同步到组件状态里。按照文档写了onChange回调,但修改内容时控制台没输出,状态也没更新,这是为什么呢?
代码是这样写的:
import { useState } from 'react';
import Editor from '@tinymce/tinymce-react';
function TextEditor() {
const [content, setContent] = useState('');
return (
<Editor
onInit={(evt, editor) => editor.setContent('初始内容')}
onChange={(evt, editor) => {
console.log('内容变化'); // 这里没触发
setContent(editor.getContent());
}}
init={{
height: 500,
menubar: false
}}
/>
);
}
试过把onChange换成onEditorChange也试过在init里配置setup回调,但问题依旧。难道还需要额外设置状态同步方式吗?
先说问题的根本原因:
onChange并不是TinyMCE官方推荐的React事件,它实际上是一个自定义的封装事件,而它的触发依赖于TinyMCE内部的input或change事件。很多时候,这些事件可能因为某些配置或者初始化顺序的问题没有正确绑定,导致回调函数无法触发。正确的解决方案是使用
onEditorChange事件,但你的代码中提到试过这个方法仍然无效,这可能是由于事件绑定的时机不对或者参数传递有问题。我们可以通过以下步骤来解决:首先,确保你安装的
@tinymce/tinymce-react版本是最新的,旧版本可能存在一些兼容性问题。你可以通过运行npm install @tinymce/tinymce-react@latest来更新。接下来,调整代码结构,确保事件绑定和状态更新的逻辑清晰且可靠。下面是修正后的代码示例:
需要注意的是,
onEditorChange是TinyMCE React封装提供的一个专用事件,专门用于监听内容的变化。它会将最新的内容作为第一个参数传递给回调函数,这样可以避免手动调用editor.getContent()的麻烦。此外,我在这里引入了
useRef来保存编辑器实例。虽然在这个例子中不是必须的,但在实际项目中,直接操作编辑器实例可能会非常有用,比如你需要在某个按钮点击时获取内容或者执行特定命令。关于为什么之前的代码不工作,主要是因为
onChange并不是一个稳定的事件,尤其是在复杂配置下,它的触发条件可能不符合预期。而onEditorChange则是专门为React设计的,能够更可靠地捕获内容变化。最后再吐槽一句,TinyMCE的React封装文档确实有点模糊,很多细节需要自己摸索。不过只要抓住核心事件机制,问题还是能顺利解决的。
onChange确实不会像 input 那样频繁触发,它是 blur 时才发,所以感觉“不更新”。真正实时响应内容变化得用onEditorChange,但你得把它放在init里配置才生效。直接复制过去试试这个写法:
关键点:
1. 不要用
onInit手动 set 内容,改用initialValue2. 实时监听靠
setup里的事件绑定,input change undo redo覆盖用户所有输入场景3.
getContent()拿到的是 HTML 字符串,更新状态没问题这样就能实时同步了。别信文档里说的
onChange,在 React 里基本就是摆设。