Next.js集成TinyMCE编辑器无法获取值,报错editor为null
解决Next.js集成TinyMCE编辑器的取值问题
先明确你的两个疑问答案:
绝对不能在handleSubmit里渲染
组件
组件必须放在页面/组件的return()JSX结构中,handleSubmit是提交触发的事件处理函数,用来处理提交逻辑,在里面渲染组件会导致编辑器无法正确挂载初始化,这就是你出现editor is null错误的核心原因之一。获取编辑器值的正确方式
你之前的写法问题出在没有正确维护编辑器实例,还错误地在onInit里处理表单数据。下面给你两种实用的实现方案:
方案一:用React Ref获取编辑器实例(适合提交时一次性取值)
如果不需要实时同步内容,只在提交时获取,用ref维护编辑器实例最稳妥:
import { useRef } from 'react'; import Editor from '@tinymce/tinymce-react'; export default function YourFormPage() { // 创建ref存储编辑器实例 const editorRef = useRef(null); const handleSubmit = (e) => { e.preventDefault(); // 用可选链避免编辑器未初始化时的null报错 const content = editorRef.current?.getContent(); if (content) { const submitData = { first: e.target.name.value, last: e.target.cat_name.value, content: content }; // 这里执行你的提交逻辑,比如发API请求 console.log(submitData); } }; return ( <form onSubmit={handleSubmit}> {/* 你的其他表单元素 */} <input type="text" name="name" placeholder="输入名称" /> <input type="text" name="cat_name" placeholder="输入分类名" /> {/* 将ref传递给Editor组件 */} <Editor ref={editorRef} initialValue="<p>This is the initial content of the editor.</p>" init={{ height: 500, menubar: false, plugins: [ 'advlist autolink lists link image charmap print preview anchor', 'searchreplace visualblocks code fullscreen', 'insertdatetime media table paste code help wordcount' ], toolbar: 'undo redo | formatselect | ' + 'bold italic backcolor | alignleft aligncenter ' + 'alignright alignjustify | bullist numlist outdent indent | ' + 'removeformat | help', content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }' }} /> <button type="submit">提交表单</button> </form> ); }
方案二:用onChange实时同步内容到状态(适合实时预览/校验场景)
如果需要实时获取编辑器内容(比如做实时预览、输入校验),可以用React状态同步:
import { useState } from 'react'; import Editor from '@tinymce/tinymce-react'; export default function YourFormPage() { // 用状态存储编辑器内容 const [editorContent, setEditorContent] = useState("<p>This is the initial content of the editor.</p>"); const handleSubmit = (e) => { e.preventDefault(); const submitData = { first: e.target.name.value, last: e.target.cat_name.value, content: editorContent }; // 执行提交逻辑 console.log(submitData); }; return ( <form onSubmit={handleSubmit}> {/* 其他表单元素 */} <input type="text" name="name" placeholder="输入名称" /> <input type="text" name="cat_name" placeholder="输入分类名" /> <Editor initialValue={editorContent} // 内容变化时同步到状态 onChange={(evt, ed) => setEditorContent(ed.getContent())} init={{ height: 500, menubar: false, plugins: [ 'advlist autolink lists link image charmap print preview anchor', 'searchreplace visualblocks code fullscreen', 'insertdatetime media table paste code help wordcount' ], toolbar: 'undo redo | formatselect | ' + 'bold italic backcolor | alignleft aligncenter ' + 'alignright alignjustify | bullist numlist outdent indent | ' + 'removeformat | help', content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }' }} /> <button type="submit">提交表单</button> </form> ); }
你原代码的核心错误点:
onInit里的e是未定义的,onInit的参数是(evt, ed),你错误引用了表单提交的e,导致逻辑混乱;- 直接赋值全局
editor变量在React组件里不可靠,组件重新渲染时会丢失引用,必须用React的useRef来维护实例; - 错误地在事件处理函数里渲染组件,导致编辑器无法正常初始化。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

